【问题标题】:Convert ndarray into 2d array where rows are the elements along the first axis将 ndarray 转换为 2d 数组,其中行是沿第一个轴的元素
【发布时间】:2017-05-07 12:31:13
【问题描述】:

我问了一个类似的问题here,但从那以后我的标准发生了一些变化。现在,我不确定这是否可以在没有循环的情况下完成,但是我想在高维数组的情况下避免循环,希望有一个通用的解决方案。

假设我们有以下 3 维数组:

arr = np.array([np.arange(1, 10).reshape((3, 3)) + i/10 for i in range(3)])
arr[0]
Out[36]: 
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]])
arr[1]
Out[37]: 
array([[ 1.1,  2.1,  3.1],
       [ 4.1,  5.1,  6.1],
       [ 7.1,  8.1,  9.1]])
arr[2]
Out[38]: 
array([[ 1.2,  2.2,  3.2],
       [ 4.2,  5.2,  6.2],
       [ 7.2,  8.2,  9.2]])

我想做的是将其转换为二维数组(列表列表也可以)。其中每一行由剩余索引的给定位置沿第一个维度的元素组成。

以下是适用于高维数组的通用解决方案:

from itertools import product:

X, *Y = arr.shape

result = np.zeros((np.prod(Y), X))

for i, y in enumerate(product(*[range(y) for y in Y])):
    for x in range(X):
        result[i, x] = arr[(x,)+y]

输出:

Out[50]: 
array([[ 1. ,  1.1,  1.2],
       [ 2. ,  2.1,  2.2],
       [ 3. ,  3.1,  3.2],
       [ 4. ,  4.1,  4.2],
       [ 5. ,  5.1,  5.2],
       [ 6. ,  6.1,  6.2],
       [ 7. ,  7.1,  7.2],
       [ 8. ,  8.1,  8.2],
       [ 9. ,  9.1,  9.2]])

对于 4D 数组:

arr = np.array([np.arange(1, 28).reshape((3, 3, 3)) + i/10 for i in range(3)])
X, *Y = arr.shape
result = np.zeros((np.prod(Y), X))
for i, y in enumerate(product(*[range(y) for y in Y])):
        for x in range(X):
            result[i, x] = arr[(x,)+y]

result
Out[62]: 
array([[  1. ,   1.1,   1.2],
       [  2. ,   2.1,   2.2],
       [  3. ,   3.1,   3.2],
       [  4. ,   4.1,   4.2],
       [  5. ,   5.1,   5.2],
       [  6. ,   6.1,   6.2],
       [  7. ,   7.1,   7.2],
       [  8. ,   8.1,   8.2],
       [  9. ,   9.1,   9.2],
       [ 10. ,  10.1,  10.2],
       [ 11. ,  11.1,  11.2],
       [ 12. ,  12.1,  12.2],
       [ 13. ,  13.1,  13.2],
       [ 14. ,  14.1,  14.2],
       [ 15. ,  15.1,  15.2],
       [ 16. ,  16.1,  16.2],
       [ 17. ,  17.1,  17.2],
       [ 18. ,  18.1,  18.2],
       [ 19. ,  19.1,  19.2],
       [ 20. ,  20.1,  20.2],
       [ 21. ,  21.1,  21.2],
       [ 22. ,  22.1,  22.2],
       [ 23. ,  23.1,  23.2],
       [ 24. ,  24.1,  24.2],
       [ 25. ,  25.1,  25.2],
       [ 26. ,  26.1,  26.2],
       [ 27. ,  27.1,  27.2]])

numpy 中是否有任何东西可以用来以这种方式重塑数组?最好不要复制?

【问题讨论】:

  • 你的 4D 机箱实际上只是 3d 的不同形状
  • 谢谢!我刚刚用 4D 编辑过。

标签: python arrays numpy multidimensional-array reshape


【解决方案1】:

这是更简单的方法:

>>> arr.reshape(3,9).T
array([[ 1. ,  1.1,  1.2],
       [ 2. ,  2.1,  2.2],
       [ 3. ,  3.1,  3.2],
       [ 4. ,  4.1,  4.2],
       [ 5. ,  5.1,  5.2],
       [ 6. ,  6.1,  6.2],
       [ 7. ,  7.1,  7.2],
       [ 8. ,  8.1,  8.2],
       [ 9. ,  9.1,  9.2]])

其他情况类似

>>> arr.reshape(3,12).T
array([[  1. ,   1.1,   1.2],
       [  2. ,   2.1,   2.2],
       [  3. ,   3.1,   3.2],
       [  4. ,   4.1,   4.2],
       [  5. ,   5.1,   5.2],
       [  6. ,   6.1,   6.2],
       [  7. ,   7.1,   7.2],
       [  8. ,   8.1,   8.2],
       [  9. ,   9.1,   9.2],
       [ 10. ,  10.1,  10.2],
       [ 11. ,  11.1,  11.2],
       [ 12. ,  12.1,  12.2]])

【讨论】:

  • 也许arr.reshape(3, -1).T 更笼统。
  • 或者更好,arr.reshape(arr.shape[0], -1).T。这(大部分)对我来说都是魔法。我不确定如果不尝试不同的 2D 整形和转置组合,我怎么会知道这样做。您能对此提供一些见解/解释吗?
  • 我找到了相同的解决方案 - 有几个反复试验的错误。 reshape(9,3) 看起来不对; reshape(3,9) 差不多了,它只需要转置。
  • 我明白了,所以我想如果你知道其中一个维度的形状,并且所有的乘积应该给出元素的数量,那么就有了开始的地方。很高兴知道
猜你喜欢
  • 2019-11-30
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 2018-10-12
  • 2021-11-29
  • 2023-03-05
  • 2019-10-29
相关资源
最近更新 更多