Python 合并numpy中的行以形成新数组
这是我试图实现的一个示例。我对python非常陌生,已经搜索了几个小时来找出我做错了什么。我还没找到我的问题所在。我还是个新手,可能在寻找错误的短语。如果是这样,你能给我指一下正确的方向吗 我想把n个数组组合成一个数组。我想让x中的第一行作为组合中的第一行,y中的第一行作为组合中的第二行,z中的第一行作为组合中的第三行,x中的第二行作为组合中的第四行,等等。 所以我看起来像这样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
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,你能扩展吗?(或者,如果您愿意,发布新的解决方案。)