如何在 Numpy 中“压缩”几个 N-D 数组?

Posted

技术标签:

【中文标题】如何在 Numpy 中“压缩”几个 N-D 数组?【英文标题】:How to "zip" several N-D arrays in Numpy? 【发布时间】:2018-01-04 21:42:48 【问题描述】:

条件如下:

1) 我们有一个 N-D 数组列表,这个列表的长度未知 M

2) 每个数组的维数相等,但未知

3) 每个数组应沿第 0 维拆分,生成的元素应沿长度为 M 的第 1 维分组,然后沿相同长度的第 0 维堆叠

4) 结果排名应为N+1,第一维的长度应为M

以上与zip 相同,但在 N-D 数组的世界中。

目前我的做法如下:

xs = [list of numpy arrays]
grs = []
for i in range(len(xs[0])):
   gr = [x[i] for x in xs] 
   gr = np.stack(gr)
   grs.append(gr)
grs = np.stack(grs)

我可以用批量操作写得更短吗?

更新

这就是我想要的

将 numpy 导入为 np

sz = 2
sh = (30, 10, 10, 3)

xs = []
for i in range(sz):
    xs.append(np.zeros(sh, dtype=np.int))

value = 0

for i in range(sz):
    for index, _ in np.ndenumerate(xs[i]):
        xs[i][index] = value
        value += 1

grs = []
for i in range(len(xs[0])):
   gr = [x[i] for x in xs]
   gr = np.stack(gr)
   grs.append(gr)
grs = np.stack(grs)

print(np.shape(grs))

此代码显然可以正常工作,生成形状为(30, 2, 10, 10, 3) 的数组。是否可以避免循环?

【问题讨论】:

嗯...如果您可以提供某种示例输入和输出,它会变得更加清晰。 然后您将从样本输入中获取尺寸,但我想避免这种情况:) 【参考方案1】:

您似乎需要对数组的第 1 维和第 2 维进行转置;您可以为此使用swapaxes

np.asarray(xs).swapaxes(1,0)

示例

xs = [np.array([[1,2],[3,4]]), np.array([[5,6],[7,8]])]
grs = []
for i in range(len(xs[0])):
    gr = [x[i] for x in xs] 
    gr = np.stack(gr)
    grs.append(gr)
grs = np.stack(grs)

grs
#array([[[1, 2],
#        [5, 6]],

#       [[3, 4],
#        [7, 8]]])

np.asarray(xs).swapaxes(1,0)
#array([[[1, 2],
#        [5, 6]],

#       [[3, 4],
#        [7, 8]]])

【讨论】:

简而言之:np.swapaxes(xs,1,0). @Divakar 酷简写。 如果我理解正确,np.asarray 应该已经将排名提高了 1,xs 中的元素排名N 所以xs 排名N+1【参考方案2】:

np.stack 接受一个轴参数;看grs的形状,我猜np.stack(xs, 1)做同样的事情。

In [490]: x
Out[490]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
In [491]: x.shape
Out[491]: (2, 3, 4)
In [494]: xs = [x, x+10, x+100]
In [495]: grs = []
     ...: for i in range(len(xs[0])):
     ...:    gr = [x[i] for x in xs] 
     ...:    gr = np.stack(gr)
     ...:    grs.append(gr)
     ...: grs = np.stack(grs)
     ...: 
In [496]: grs
Out[496]: 
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]],

        [[100, 101, 102, 103],
         [104, 105, 106, 107],
         ...
         [116, 117, 118, 119],
         [120, 121, 122, 123]]]])
In [497]: grs.shape
Out[497]: (2, 3, 3, 4)

测试np.stack:

In [499]: np.allclose(np.stack(xs, 1),grs)
Out[499]: True

【讨论】:

以上是关于如何在 Numpy 中“压缩”几个 N-D 数组?的主要内容,如果未能解决你的问题,请参考以下文章

使用 n-d numpy 数组作为索引对 Panda 的数据帧进行分层索引

将具有 n 级分层索引的 Pandas DataFrame 转换为 n-D Numpy 数组

如何将 N-D 数组的最后两个维度作为 2D 数组?

我如何“压缩排序”并行numpy数组?

如何在 MATLAB MEX 文件中创建双精度的 N-D 矩阵?

从压缩字节加载 numpy 数组