合并numpy中的行以形成新数组

时间:2018-06-25 08:27:12

标签: python arrays numpy

这是我要完成的工作的一个示例。我是python的新手,已经搜寻了数小时来找出我做错了什么。我一直找不到我的问题所在。我还很新,可能正在搜索错误的短语。如果是这样,请您指出正确的方向吗?

我想将n个数组组合成一个数组。我想将x的第一行作为合并的第一行,y的第一行作为合并的第二行,z的第一行作为第三行合并,x的第二行作为第四行合并结合等 所以我看起来像这样。

x = [x1 x2 x3]
    [x4 x5 x6]
    [x7 x8 x9]

y = [y1 y2 y3]
    [y4 y5 y6]
    [y7 y8 y9]

x = [z1 z2 z3]
    [z4 z5 z6]
    [z7 z8 z9]

combined = [x1 x2 x3]
           [y1 y2 y3]
           [z1 z2 z3]
           [x4 x5 x6]
           [...]
           [z7 z8 z9]

我能想到的最好的是

    import numpy as np

x = np.random.rand(6,3)
y = np.random.rand(6,3)
z = np.random.rand(6,3)

combined = np.zeros((9,3))

for rows in range(len(x)):        
    combined[0::3] = x[rows,:] 
    combined[1::3] = y[rows,:]
    combined[2::3] = z[rows,:]


print(combined)

所有这些操作就是将输入数组的最后一个值写入输出数组中的每第三行,而不是我想要的。我不确定这是否是最好的方法。任何建议都会有所帮助。

*我只是想知道这是可行的,但是如果有人知道更高性能的方法,请*让我知道。

import numpy as np

x = np.random.rand(6,3) 
y = np.random.rand(6,3) 
z = np.random.rand(6,3)

combined = np.zeros((18,3))

for rows in range(6):        
  combined[rows*3,:] = x[rows,:] 
  combined[rows*3+1,:] = y[rows,:]
  combined[rows*3+2,:] = z[rows,:]

  print(combined)

5 个答案:

答案 0 :(得分:3)

您可以使用列表理解和zip来做到这一点:

combined = np.array([row for row_group in zip(x, y, z) for row in row_group])

答案 1 :(得分:2)

仅使用向量化操作:

A = np.vstack((x, y, z))
idx = np.arange(A.shape[0]).reshape(-1, x.shape[0]).T.flatten()

A = A[idx]

这是一个演示:

import numpy as np

x, y, z = np.random.rand(3,3), np.random.rand(3,3), np.random.rand(3,3)

print(x, y, z)

[[ 0.88259564  0.17609363  0.01067734]
 [ 0.50299357  0.35075811  0.47230915]
 [ 0.751129    0.81839586  0.80554345]]
[[ 0.09469396  0.33848691  0.51550685]
 [ 0.38233976  0.05280427  0.37778962]
 [ 0.7169351   0.17752571  0.49581777]]
[[ 0.06056544  0.70273453  0.60681583]
 [ 0.57830566  0.71375038  0.14446909]
 [ 0.23799775  0.03571076  0.26917939]]

A = np.vstack((x, y, z))
idx = np.arange(A.shape[0]).reshape(-1, x.shape[0]).T.flatten()

print(idx)  # [0 3 6 1 4 7 2 5 8]

A = A[idx]

print(A)

[[ 0.88259564  0.17609363  0.01067734]
 [ 0.09469396  0.33848691  0.51550685]
 [ 0.06056544  0.70273453  0.60681583]
 [ 0.50299357  0.35075811  0.47230915]
 [ 0.38233976  0.05280427  0.37778962]
 [ 0.57830566  0.71375038  0.14446909]
 [ 0.751129    0.81839586  0.80554345]
 [ 0.7169351   0.17752571  0.49581777]
 [ 0.23799775  0.03571076  0.26917939]]

答案 2 :(得分:1)

我对您的代码做了一些更改,以获得所需的输出

import numpy as np

x = np.random.rand(6,3)
y = np.random.rand(6,3)
z = np.random.rand(6,3)

combined = np.zeros((18,3))

combined[0::3] = x
combined[1::3] = y
combined[2::3] = z

print(combined)

您合并的矩阵的形状不正确,并且真正不需要for循环。

答案 3 :(得分:0)

这可能不是最Python的方式,但您可以

for block in range(len(combined)/3):
    for rows in range(len(x)):

    combined[block*3+0::3] = x[rows,:] 
    combined[block*3+1::3] = y[rows,:]
    combined[block*3+2::3] = z[rows,:]

答案 4 :(得分:0)

一个简单的numpy解决方案是在新的中轴上stack排列数组,并将结果重塑为2d:

In [5]: x = np.arange(9).reshape(3,3)
In [6]: y = np.arange(9).reshape(3,3)+10
In [7]: z = np.arange(9).reshape(3,3)+100
In [8]: np.stack((x,y,z),axis=1).reshape(-1,3)
Out[8]: 
array([[  0,   1,   2],
       [ 10,  11,  12],
       [100, 101, 102],
       [  3,   4,   5],
       [ 13,  14,  15],
       [103, 104, 105],
       [  6,   7,   8],
       [ 16,  17,  18],
       [106, 107, 108]])

如果我们给每个维度一个不同的值,可能会更容易看到正在发生的事情;例如2个3x4阵列:

In [9]: x = np.arange(12).reshape(3,4)
In [10]: y = np.arange(12).reshape(3,4)+10

np.array在新的第1轴上合并它们,形成2x3x4数组。为了获得所需的交错,我们可以对前2个维度进行转置,生成3x2x4。然后重塑为6x4。

In [13]: np.array((x,y))
Out[13]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[10, 11, 12, 13],
        [14, 15, 16, 17],
        [18, 19, 20, 21]]])
In [14]: np.array((x,y)).transpose(1,0,2)
Out[14]: 
array([[[ 0,  1,  2,  3],
        [10, 11, 12, 13]],

       [[ 4,  5,  6,  7],
        [14, 15, 16, 17]],

       [[ 8,  9, 10, 11],
        [18, 19, 20, 21]]])
In [15]: np.array((x,y)).transpose(1,0,2).reshape(-1,4)
Out[15]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [ 4,  5,  6,  7],
       [14, 15, 16, 17],
       [ 8,  9, 10, 11],
       [18, 19, 20, 21]])

np.vstack产生6x4,但顺序错误。我们不能直接转置它。

具有默认轴的

np.stack的行为与np.array相似。但是使用axis=1,它会创建一个3x2x4,我们可以对其进行调整:

In [16]: np.stack((x,y), 1)
Out[16]: 
array([[[ 0,  1,  2,  3],
        [10, 11, 12, 13]],

       [[ 4,  5,  6,  7],
        [14, 15, 16, 17]],

       [[ 8,  9, 10, 11],
        [18, 19, 20, 21]]])

接受的答案中的列表邮政编码为transpose的列表版本,创建了3个2元素元组的列表。

In [17]: list(zip(x,y))
Out[17]: 
[(array([0, 1, 2, 3]), array([10, 11, 12, 13])),
 (array([4, 5, 6, 7]), array([14, 15, 16, 17])),
 (array([ 8,  9, 10, 11]), array([18, 19, 20, 21]))]

np.array(list(zip(x,y)))产生与stack相同的东西,一个3x2x4数组。


关于速度,我怀疑分配和分配(如Ash的回答所示)最快:

In [27]: z = np.zeros((6,4),int)
    ...: for i, arr in enumerate((x,y)):
    ...:     z[i::2,:] = arr
    ...:     
In [28]: z
Out[28]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [ 4,  5,  6,  7],
       [14, 15, 16, 17],
       [ 8,  9, 10, 11],
       [18, 19, 20, 21]])

对于严重的时间安排,请使用比这大得多的示例。