简体   繁体   English

使用由整数 [0,...,L-1] 索引的额外列将 numpy 数组 (N,M,L) 转换为 (N*L,M+1)

[英]Transform numpy array (N,M,L) into (N*L,M+1) with the extra column indexed by integer [0,…,L-1]

Let us consider this simple example:让我们考虑这个简单的例子:

import numpy as np

a=np.arange(90)
a=a.reshape(6,3,5)

I would like to get an array b of shape (6*5,3+1=4) with我想得到一个形状为 (6*5,3+1=4) 的数组b

b[0:6,0]=a[:,0,0]
b[0:6,1]=a[:,1,0]
b[0:6,2]=a[:,2,0]
b[0:6,3]=0

b[6:12,0]=a[:,0,1]
b[6:12,1]=a[:,1,1]
b[6:12,2]=a[:,2,1]
b[6:12,3]=1
...

I can do it with for-loops but I'm sure there are much more elegant solutions.我可以用 for 循环来做到这一点,但我相信还有更优雅的解决方案。

I'd first reorder the axes of your array, then allocate the larger resulting array, then use two (broadcasting) assignments to set the new values:我首先对数组的轴重新排序,然后分配更大的结果数组,然后使用两个(广播)分配来设置新值:

import numpy as np

a = np.arange(6*3*5).reshape(6, 3, 5)  # shape (N, M, L)

aux = a.transpose(0, 2, 1)  # shape (N, L, M)
res = np.empty_like(a, shape=aux.shape[:-1] + (aux.shape[-1] + 1,))
res[..., :-1] = aux  # (N, L, M)-shaped slice
res[..., -1] = np.arange(aux.shape[1])  # (N, L)-shaped slice

# two different interpretations:
#res = res.reshape(-1, res.shape[-1])  # shape (N*L, M + 1)
res = res.transpose(0, 1, 2).reshape(-1, res.shape[-1])  # shape (N*L, M + 1)

Of the two interpretations of your question, the latter (uncommented version) reproduces your "dirty version" posted in a comment.在您的问题的两种解释中,后者(未注释版本)复制了您在评论中发布的“脏版本”。 If this is really what you need, we could do the original transpose in a way that puts the L -sized axis first:如果这确实是您所需要的,我们可以以将L轴放在首位的方式进行原始转置:

import numpy as np

a = np.arange(6*3*5).reshape(6, 3, 5)  # shape (N, M, L)

aux = a.transpose(2, 0, 1)  # shape (L, N, M)
res = np.empty_like(a, shape=aux.shape[:-1] + (aux.shape[-1] + 1,))
res[..., :-1] = aux  # (L, N, M)-shaped slice
res[..., -1] = np.arange(aux.shape[0])[:, None]  # (L, N)-shaped slice

res = res.reshape(-1, res.shape[-1])  # shape (N*L, M + 1)
a_new = a.transpose(0, 2, 1).reshape(N*L, M, order="F")
extra_column = np.repeat(np.arange(L), N)
b = np.column_stack((a_new, extra_column))

We first swap the last 2 axes of a with transpose and then reshape it to desired shape but with F ortran order to match the output.我们首先交换的最后2个轴atranspose ,然后reshape它所需的形状,但与F ortran以便输出相匹配。 Extra column is produced with repeated np.arange(L) and added with column_stack .额外的列是用重复的np.arange(L)生成的,并添加了column_stack


Sample run:示例运行:

>>> N, M, L = 6, 3 ,5
>>> a = np.arange(N*M*L).reshape(N, M, L)
>>> # above operations...
>>> b

array([[ 0,  5, 10,  0],
       [15, 20, 25,  0],
       [30, 35, 40,  0],
       [45, 50, 55,  0],
       [60, 65, 70,  0],
       [75, 80, 85,  0],
       [ 1,  6, 11,  1],
       [16, 21, 26,  1],
       [31, 36, 41,  1],
       [46, 51, 56,  1],
       [61, 66, 71,  1],
       [76, 81, 86,  1],
       [ 2,  7, 12,  2],
       [17, 22, 27,  2],
       [32, 37, 42,  2],
       [47, 52, 57,  2],
       [62, 67, 72,  2],
       [77, 82, 87,  2],
       [ 3,  8, 13,  3],
       [18, 23, 28,  3],
       [33, 38, 43,  3],
       [48, 53, 58,  3],
       [63, 68, 73,  3],
       [78, 83, 88,  3],
       [ 4,  9, 14,  4],
       [19, 24, 29,  4],
       [34, 39, 44,  4],
       [49, 54, 59,  4],
       [64, 69, 74,  4],
       [79, 84, 89,  4]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM