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

Python 合并numpy中的行以形成新数组,python,arrays,numpy,Python,Arrays,Numpy,这是我试图实现的一个示例。我对python非常陌生,已经搜索了几个小时来找出我做错了什么。我还没找到我的问题所在。我还是个新手,可能在寻找错误的短语。如果是这样,你能给我指一下正确的方向吗 我想把n个数组组合成一个数组。我想让x中的第一行作为组合中的第一行,y中的第一行作为组合中的第二行,z中的第一行作为组合中的第三行,x中的第二行作为组合中的第四行,等等。 所以我看起来像这样 x = [x1 x2 x3] [x4 x5 x6] [x7 x8 x9] y = [y1 y2 y3

这是我试图实现的一个示例。我对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)

您可以使用列表和
zip

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

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

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循环。

这可能不是最适合的方式,但你可以

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,:]

仅使用矢量化操作:

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]]

一个简单的
numpy
解决方案是
将数组堆叠在一个新的中轴上,并将结果重塑为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]])
如果我们给每个维度一个不同的值,可能更容易看到发生了什么;e、 g.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
类似。但当轴=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]]])

接受答案中的列表zip是
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))
产生与
堆栈相同的东西,一个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]])

对于严肃的时间安排,请使用比这更大的例子。

@Jundiaius解决方案更优雅,
pythonic
当我昨天读了你的文章并误读了它时,我筋疲力尽了。在我删除for循环并复制了您的代码之后,它是最快的。谢谢你发帖。你是个救命恩人。我知道行是指行计数的迭代值,但我不确定在此代码中迭代的是哪个行组。性能说明:
zip
与NumPy数组一起使用效率不高,例如,请参见。我对这两种方法都使用了timeit。我得到了576个我们的拉链和589个与for循环足够接近的时间,我会认为它们在我的应用程序相同。在这一点上,学习更多关于python的知识更为重要,JPP您有其他代码可以测试吗?@chadjensen,对于小数组,当然,这是无关紧要的。对于较大的阵列,您应该以矢量化解决方案为目标。我在回答中给出了一个答案。这是一个聪明而美丽的答案!略快于zip,每圈576美元。这对我这样的傻瓜来说更难理解。我必须研究一下命令的各个部分,看看我是否能掌握它。这并不太复杂,你需要了解的主要事情是如何
numpy.arange
(以数组的形式获取范围)、
numpy.reformate
(此处以二维数组的形式重新塑造)和
展平(形成一维数组)。合并以获得索引
[0 3 6 1 4 7 2 5 8]
。如何使用轴1进行
堆叠
,再加上
重塑
?感谢您与我分享您的知识。我还有很多东西要学,很高兴有人愿意帮忙。@hpaulj,你能扩展吗?(或者,如果您愿意,发布新的解决方案。)