ShanZhengYang
ShanZhengYang

Reputation: 17631

How to concatenate these two numpy arrays?

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

Answers (3)

hpaulj
hpaulj

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

ali_m
ali_m

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

Eric
Eric

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

Related Questions