Reputation: 17631
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.
Upvotes: 0
Views: 104
Reputation: 231385
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]])
Upvotes: 1
Reputation: 74172
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)}
Upvotes: 1
Reputation: 97571
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
})
Upvotes: 2