Given 2 numPy arrays of length N, I would like to create a pairwise 2D array (N x N) based on a custom function.
JavaScript
x
9
1
import numpy as np
2
import pandas as pd
3
4
A = np.array(A) # size N
5
B = np.array(B) # size N
6
Fij = f(A[i], B[i], A[j], B[j])
7
8
# f is a pairwise function of Ai, Bi and Aj, Bj
9
I would like to create an array C of size NxN. such that
JavaScript
1
2
1
C = Fij # with i, j in range(N)
2
Example:
JavaScript
1
7
1
A = [1,2,3,4]
2
B = ['a', 'b', 'c', 'd']
3
4
def f(i,j):
5
return str(A[i]+A[j])+B[i]+B[j]
6
# f(0,1) = 3ab
7
I would like to create
JavaScript
1
5
1
C = [[2aa, 3ab, 4ac, 5ad],
2
[3ba, 4bb, 5bc, 6bd],
3
[4ca, 5cb, 6cc, 7cd],
4
[5da, 6db, 7dc, 8dd]]
5
I know I can do this by nested loop:
JavaScript
1
5
1
C=np.empty([N, N])
2
for i in range(N):
3
for j in range(N):
4
C[i, j] = f(i,j)
5
but looking for a neat and more efficient solution.
Advertisement
Answer
In numpy you can make a nice solution by using +
to both add the integers and concatenate the characters.
JavaScript
1
7
1
A = np.array([1,2,3,4])
2
B = np.char.array(['a', 'b', 'c', 'd']) # char array so can use "+" instead of "add"
3
4
A0 = A[:,None] + A[None,:] # add the integers
5
B0 = B[:,None] + B[None,:] # concatenate the characters
6
C = A0.astype('<U1') + B0
7
Or as a single line:
JavaScript
1
2
1
C = (A[:,None] + A[None,:]).astype('<U1') + B[:,None] + B[None,:]
2
Printing out each line in the above, gives:
JavaScript
1
18
18
1
A0
2
[[2 3 4 5]
3
[3 4 5 6]
4
[4 5 6 7]
5
[5 6 7 8]]
6
7
B0
8
[['aa' 'ab' 'ac' 'ad']
9
['ba' 'bb' 'bc' 'bd']
10
['ca' 'cb' 'cc' 'cd']
11
['da' 'db' 'dc' 'dd']]
12
13
C
14
[['2aa' '3ab' '4ac' '5ad']
15
['3ba' '4bb' '5bc' '6bd']
16
['4ca' '5cb' '6cc' '7cd']
17
['5da' '6db' '7dc' '8dd']]
18