0

This is a simple operation I am having trouble accomplishing with numpy:

I have two numpy arrays:

import numpy as np
arr1 = np.array([12, 13, 14, 15])
arr2 = np.array([100, 200, 300, 400])

I would like four distinct numpy arrays:

a1 = np.array([12, 13, 14, 15, 100])
a2 = np.array([12, 13, 14, 15, 200])
a3 = np.array([12, 13, 14, 15, 300])
a4 = np.array([12, 13, 14, 15, 400])

What's the most "numpythonic" way to accomplish this?

I could repeat the first array using numpy.tile, e.g.

repeats = np.tile(arr1, len(arr2))

But that's not optimal.

3 Answers 3

2

I would like four distinct numpy arrays:

Are you sure you don't want one array, np.array([a1, a2, a3, a4])?

But that's not optimal.

If optimality is your concern, preallocating results in the fewest copies:

N = len(arr1)
M = len(arr2)
result = np.zeros((M, N + 1)
result[:,:N] = arr1
result[:,N] = arr2

If you really want to be able to write this kind of thing as an expression, you could define:

def build_arr(into, parts):
    for sl, val in parts.items():
        into[sl] = val
    return into

result = build_arr(np.zeros(M, N + 1), {
    np.s_[:,:N]: arr1,
    np.s_[:,N]:  arr2
})
Sign up to request clarification or add additional context in comments.

Comments

1

I would use np.hstack and a generator expression:

a1, a2, a3, a4 = (np.hstack((arr1, v)) for v in arr2)

If you have a variable number of elements in arr2 then you could store the resulting arrays in a list rather than unpacking them to variable names:

arrs = [np.hstack((arr1, v)) for v in arr2]

Dynamically creating variables is almost always a bad idea. If you want a variable number of named arrays then I suggest you store them in a dict or some other named Python structure. You could use a dict comprehension:

named_arrs = {'a%i' % (i + 1): np.hstack((arr1, v)) for i, v in enumerate(arr2)}

6 Comments

a1, a2, a3, a4 What if I don't know a priori the number of arrays which should be generated? One would have to use the length of arr2
@ShanZhengYang: Do you really want to create a dynamic number of variable names? That's a really bad idea
"I would like four distinct numpy arrays". You could easily collect the subarrays in a list if you don't want to unpack them to separate variable names, e.g. arrs = [np.hstack((arr1, v)) for v in arr2].
@ali_m "I would like four distinct numpy arrays"---yeah, I'm sorry---it's annoying when OPs do this. I should have given the above as an example first.
So which one do you want? Four separate arrays or one array with four rows?
|
1

I rather like the use of tile:

In [1684]: np.tile(arr1,[arr2.shape[0],1])
Out[1684]: 
array([[12, 13, 14, 15],
       [12, 13, 14, 15],
       [12, 13, 14, 15],
       [12, 13, 14, 15]])
In [1685]: np.concatenate((np.tile(arr1,[arr2.shape[0],1]),arr2[:,None]),axis=1)
Out[1685]: 
array([[ 12,  13,  14,  15, 100],
       [ 12,  13,  14,  15, 200],
       [ 12,  13,  14,  15, 300],
       [ 12,  13,  14,  15, 400]])

Such a 2d array is handy in itself. But it can be split into arrays:

In [1686]: np.split(_,arr2.shape[0])
Out[1686]: 
[array([[ 12,  13,  14,  15, 100]]),
 array([[ 12,  13,  14,  15, 200]]),
 array([[ 12,  13,  14,  15, 300]]),
 array([[ 12,  13,  14,  15, 400]])]

And if you really need separate names for those arrays, unpack the list:

In [1687]: a1,a2,a3,a4=_
In [1688]: a1
Out[1688]: array([[ 12,  13,  14,  15, 100]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.