Concatenate a Numpy Array to Another Numpy Array

Concatenate a NumPy array to another NumPy array

In [1]: import numpy as np

In [2]: a = np.array([[1, 2, 3], [4, 5, 6]])

In [3]: b = np.array([[9, 8, 7], [6, 5, 4]])

In [4]: np.concatenate((a, b))
Out[4]:
array([[1, 2, 3],
[4, 5, 6],
[9, 8, 7],
[6, 5, 4]])

or this:

In [1]: a = np.array([1, 2, 3])

In [2]: b = np.array([4, 5, 6])

In [3]: np.vstack((a, b))
Out[3]:
array([[1, 2, 3],
[4, 5, 6]])

Concatenating two one-dimensional NumPy arrays

Use:

np.concatenate([a, b])

The arrays you want to concatenate need to be passed in as a sequence, not as separate arguments.

From the NumPy documentation:

numpy.concatenate((a1, a2, ...), axis=0)

Join a sequence of arrays together.

It was trying to interpret your b as the axis parameter, which is why it complained it couldn't convert it into a scalar.

Concatenating 2 dimensional numpy arrays in Python

You can use hstack and vector broadcasting for that:

a = np.array([[1,2,3],[3,4,5],[6,7,8]])  
b = np.array([9,10,11])
res = np.hstack((a, b[:,None]))
print(res)

Output:

[[ 1  2  3  9]
[ 3 4 5 10]
[ 6 7 8 11]]

Note that you cannot use concatenate because the array have different shapes. hstack stack horizontally the multi-dimentional arrays so it just add a new line at the end here. A broadcast operation (b[:,None]) is needed so that the appended vector is a vertical one.

How to append a numpy Array into another one

In [103]: train_X = np.ndarray([])
...: print(train_X.shape)
...: for i in range(3):
...: vectorized_img = np.ones((4, 1))
...: train_X = np.append(train_X, vectorized_img, axis=1)
...:
()
Traceback (most recent call last):
File "<ipython-input-103-26d2205beb4e>", line 5, in <module>
train_X = np.append(train_X, vectorized_img, axis=1)
File "<__array_function__ internals>", line 5, in append
File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 4745, in append
return concatenate((arr, values), axis=axis)
File "<__array_function__ internals>", line 5, in concatenate
ValueError: zero-dimensional arrays cannot be concatenated

np.append just calls np.concatenate. One argument has shape (), the other (4,1). The error is that it can't join those.

np.ndarray([]) is NOT a clone of [], and np.append is not a clone of list append. concatenate says that the number of dimensions must match, and the size of the dimensions must also match (except for the concatenate one).

To join 'columns' we need to start with a 'column'

In [111]: train_X = np.ones((4,0))
...: for i in range(3):
...: vectorized_img = np.ones((4, 1))
...: train_X = np.append(train_X, vectorized_img, axis=1)
...: train_X.shape
Out[111]: (4, 3)

Or we could start with (0,1) and join on axis=0.

But it's faster, and less prone to errors it we stick with list append:

In [114]: alist = []
...: for i in range(3):
...: vectorized_img = np.ones((4, 1))
...: alist.append(vectorized_img)
...: np.concatenate(alist, axis=1)
Out[114]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])

Concatenate two arrays of different dimensions numpy

You can use vstack for this:

import numpy as np

a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.array([7,8,9])

d = np.vstack((a,b))

e = np.vstack((d, c))

print(d)
print(e)

Gives:

[[1 2 3]
[4 5 6]]

[[1 2 3]
[4 5 6]
[7 8 9]]

Concatenating two numpy array

Use np.concatenate, in axis parameter you define direction of concatenation.

>>> import numpy as np
>>> a = np.zeros((100,1,300,1))
>>> b = np.zeros((100,1,400,1))
>>> c = np.concatenate((a,b),axis=2)
>>> c.shape
(100, 1, 700, 1)

Concatenate multiple numpy array present in a list?

In your case you can easily just use:

f_0_1 = np.concatenate(features_0_1)

As you can see, you dont need to pass each array from ndarray to concatenate(). The function does it on it's own.

Manipulating numpy arrays (concatenating inner sub-arrays)

From your new update, you can do the following using np.lib.stride_tricks.as_strided:

>>> np.lib.stride_tricks.as_strided(a, shape=(3,3,2,2,3), strides=(72,24,216,12,4))
array([[[[[ 10, 20, 30],
[ 40, 40, 20]],

[[ 20, 40, 60],
[ 80, 80, 40]]],

[[[ 22, 44, 66],
[ 88, 88, 44]],

[[ 44, 88, 132],
[176, 176, 88]]],

[[[ 33, 66, 99],
[132, 132, 66]],

[[ 66, 132, 198],
[264, 264, 132]]]],

[[[[ 22, 44, 66],
[ 88, 88, 44]],

[[ 44, 88, 132],
[176, 176, 88]]],

[[[ 54, 108, 162],
[216, 216, 108]],

[[108, 216, 324],
[432, 432, 216]]],

[[[ 23, 46, 69],
[ 92, 92, 46]],

[[ 46, 92, 138],
[184, 184, 92]]]],

[[[[ 14, 28, 42],
[ 56, 56, 28]],

[[ 28, 56, 84],
[112, 112, 56]]],

[[[ 25, 50, 75],
[100, 100, 50]],

[[ 50, 100, 150],
[200, 200, 100]]],

[[[ 33, 66, 99],
[132, 132, 66]],

[[ 66, 132, 198],
[264, 264, 132]]]]])

Explanation:

Take another example: a small array q and our desired output after changing q:

>>> q = np.arange(12).reshape(4,3,-1)
>>> q
array([[[ 0],
[ 1],
[ 2]],

[[ 3],
[ 4],
[ 5]],

[[ 6],
[ 7],
[ 8]],

[[ 9],
[10],
[11]]])
# desired output:
# shape = (2, 3, 2)
array([[[ 0, 6],
[ 1, 7],
[ 2, 8]],

[[ 3, 9],
[ 4, 10],
[ 5, 11]]])

Here we are using numpy strides to achieve this. Let's check for q's strides:

>>> q.strides
(12, 4, 4)

In our output, all strides should remain the same, except the third stride, because in the third dimension we need to stack with the values from bottom half of q, ie: 6 is put next to 0, 7 next to 1 and so on...

So, how "far" is it from 0 to 6 ? Or in another word, how far is it from q[0,0,0] to q[2,0,0] ?

# obviously, distance = [2,0,0] - [0,0,0] = [2,0,0]
bytedistance = np.sum(np.array([2,0,0])*q.strides)
# 2*12 + 0*4 + 0*4 = 24 bytes

Okay then new_strides = (12, 4, 24) and hence we got:

>>> np.lib.stride_tricks.as_strided(q, shape=(2,3,2), strides=new_strides)
array([[[ 0, 6],
[ 1, 7],
[ 2, 8]],

[[ 3, 9],
[ 4, 10],
[ 5, 11]]])

Back to your question:

a.strides = (72,24,12,4)
new_strides = (72,24,216,12,4) # why is 216 here ? it's a homework :)
new_a = np.lib.stride_tricks.as_strided(a, shape=(3,3,2,2,3), strides=new_strides)


Related Topics



Leave a reply



Submit