I have two numpy arrays like this,
data1 = np.array([[17, 48],
[17, 53],
[17, 55]])
data2 = np.array([100,200])
I want to combine those arrays by adding 1 at the beginning of the each one.
I tried,
out = []
for i in data1:
for j in data2:
out.append([1,i,j])
np.array(out)
#array([[1, array([17, 48]), 100],
# [1, array([17, 48]), 200],
# [1, array([17, 53]), 100],
# [1, array([17, 53]), 200],
# [1, array([17, 55]), 100],
# [1, array([17, 55]), 200]], dtype=object)
But the output is not the one I desire. The expected one is like below.
data_desired = np.array([[1,17,48,100],
[1,17,48,200],
[1,17,53,100],
[1,17,53,200],
[1,17,55,100],
[1,17,55,200]])
By the way, using loop seems also wrong to me. Maybe there exist some other alternatives like broadcasting, newaxis etc?
Thanks in advance!
CodePudding user response:
You can use the unpacking operator * to unpack i. This is probably the easiest fix for your situation.
out = []
for i in data1:
for j in data2:
out.append([1,*i,j])
np.array(out)
CodePudding user response:
If speed is relevant and you are going to use large arrays, you shouldn't use loops or growing data structures:
>>> n1 = len(data1)
>>> n2 = len(data2)
>>> result = np.empty_like(data1, shape=(n1*n2, 4))
>>> result[:, 0] = 1
>>> result[:, 1:3] = np.repeat(data1, n2, axis=0)
>>> result[:, 3] = np.repeat(data2[None, :], m1, axis=0).ravel()
>>> result
array([[ 1, 17, 48, 100],
[ 1, 17, 48, 200],
[ 1, 17, 53, 100],
[ 1, 17, 53, 200],
[ 1, 17, 55, 100],
[ 1, 17, 55, 200]])
CodePudding user response:
A variant on @aerobiomat's answer, using broadcasting instead of repeat to fill in the data. reshape produces a view, so assignment to it affects res itself. Working this out took some experimenting, so it's not necessarily superior.
In [141]: res = np.ones((6,4),data1.dtype)
In [142]: res.reshape((3,2,4))[:,:,1:3]=data1[:,None,:]
In [143]: res.reshape((3,2,4))[:,:,3]=data2
In [144]: res
Out[144]:
array([[ 1, 17, 48, 100],
[ 1, 17, 48, 200],
[ 1, 17, 53, 100],
[ 1, 17, 53, 200],
[ 1, 17, 55, 100],
[ 1, 17, 55, 200]])
The reshaped array looks like:
In [145]: res.reshape((3,2,4))
Out[145]:
array([[[ 1, 17, 48, 100],
[ 1, 17, 48, 200]],
[[ 1, 17, 53, 100],
[ 1, 17, 53, 200]],
[[ 1, 17, 55, 100],
[ 1, 17, 55, 200]]])
