1

I would like to create a function that adds together a 3 element array. with other 3 elements arrays to create a multidimensional array, for instance, with 2 arrays:

parameter1 = [29.9, 30,  30.1]
parameter2 = [19.9, 20,  20.1]

multiarray = AddElements(parameter1, parameter2)

multiarray outputs:

[[[29.9 19.9]
  [29.9 20. ]
  [29.9 20.1]]

 [[30.  19.9]
  [30.  20. ]
  [30.  20.1]]

 [[30.1 19.9]
  [30.1 20. ]
  [30.1 20.1]]]

Are there any numpy functions for instance that can help me with this? And it would be even better if it can perform this operation with more than 2 arrays.

Brian Barbieri
  • 293
  • 2
  • 15

2 Answers2

3
In [441]: parameter1 = [29.9, 30,  30.1] 
     ...: parameter2 = [19.9, 20,  20.1]                                        

itertools has a handy product function:

In [442]: import itertools                                                      
In [443]: list(itertools.product(parameter1, parameter2))                       
Out[443]: 
[(29.9, 19.9),
 (29.9, 20),
 (29.9, 20.1),
 (30, 19.9),
 (30, 20),
 (30, 20.1),
 (30.1, 19.9),
 (30.1, 20),
 (30.1, 20.1)]

This list can be put in your desired array form with:

In [444]: np.array(_).reshape(3,3,2)                                            
Out[444]: 
array([[[29.9, 19.9],
        [29.9, 20. ],
        [29.9, 20.1]],

       [[30. , 19.9],
        [30. , 20. ],
        [30. , 20.1]],

       [[30.1, 19.9],
        [30.1, 20. ],
        [30.1, 20.1]]])

Adding another list:

In [447]: C=list(itertools.product(parameter1, parameter2, parameter1))         
In [448]: np.array(C).reshape(3,3,3,-1)   

Using just numpy functions:

np.stack(np.meshgrid(parameter1,parameter2,indexing='ij'), axis=2) 

The itertools.product approach is faster.

Also inspired by the duplicate answers:

def foo(alist):
    a,b = alist  # 2 item for now
    res = np.zeros((a.shape[0], b.shape[0],2))
    res[:,:,0] = a[:,None]
    res[:,:,1] = b
    return res
foo([np.array(parameter1), np.array(parameter2)])

With this example it times about the same as itertools.product.

In [502]: alist = [parameter1,parameter2,parameter1,parameter1]                 
In [503]: np.stack(np.meshgrid(*alist,indexing='ij'), axis=len(alist)).shape    
Out[503]: (3, 3, 3, 3, 4)
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Upvoted. Worth mentioning in your answer that the `meshgrid` approach cannot be easily extended to the case where there are more than 2 arrays. – fountainhead Feb 25 '19 at 05:36
  • I added a larger `meshgrid` case. Extension is as easy for that, maybe even easier. – hpaulj Feb 25 '19 at 05:46
1

I think there are existing numpy functions that may do this more efficiently, but this solution should give you the correct output.

import numpy as np

a = [29.9, 30,  30.1]
b = [19.9, 20,  20.1]

compound_list = [[[ai, bi] for bi in b] for ai in a]
print(np.array(compound_list))

output:

[[[29.9 19.9]
  [29.9 20. ]
  [29.9 20.1]]

 [[30.  19.9]
  [30.  20. ]
  [30.  20.1]]

 [[30.1 19.9]
  [30.1 20. ]
  [30.1 20.1]]]
  • Thank you for this quick explanation, is there also a way to do this for more than 2 lists, without hardcoding the amount of lists you do this operation on? – Brian Barbieri Feb 24 '19 at 19:05