Consider two arrays A and B, both of dimension NxN. I wish to generate a new array NxN such that each new element is a tuple (or list, doesn't really matter) of the type (A_ij,B_ij).

I can do it by running element by element like:

def recombine(A,B):
    NewArray=[]
    for i in range(len(A)):
        NewArray.append([])
        for j in range(len(B)):
            NewArray[i].append(A[i][j],B[i][j])
    return NewArray

which is a very memory consuming algorithm.

I was wondering if there is a more efficient way (taking advantage of numpy array for doing this).

To clarify, let's consider the following example (where, for simplicity, I am considering simple lists instead of np arrays):

A=[[1,2],[3,4]]
B=[[10,20],[30,40]]

#I want an output in the form:

[[(1,10),(2,20)],[(3,30),(4,40)]]
3

There are 3 best solutions below

0
tdelaney On BEST ANSWER

You can use nested zip. zip yields tuples from a set of iterables where each item in the tuple is the next value of each iterable in turn. First you zip A and B which yields sublists in A and B, then a second zip to flip them.

>>> A=[[1,2],[3,4]]
>>> B=[[10,20],[30,40]]
>>> [list(zip(*zipped)) for zipped in zip(A,B)]
[[(1, 10), (2, 20)], [(3, 30), (4, 40)]]
0
tax evader On

I think np.dstack can be used in this case but. You can use the built-in zip function if you don't want to use external libraries. Theoretically, the performance should be relatively the same O(n*n) since you have to iterate through all elements in the 2D array to generate a new array but numpy should be slightly more efficient due to memory, locality optimization

A=[[1,2],[3,4]]
B=[[10,20],[30,40]]

def recombine(A,B):
    return [list(zip(A[i], B[i])) for i in range(len(A))]

print(recombine(A,B))
import numpy as np

print(np.dstack((A,B)))
0
Chams Agouni On
import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[10, 20], [30, 40]])

def combine(A, B):
    result_array = np.dstack((A, B))
    return [[tuple(pair) for pair in row] for row in result_array]

print(combine(A, B))