将ndarray转换为2d数组,其中行是沿第一个轴的元素

时间:2016-12-21 23:39:22

标签: python arrays numpy multidimensional-array reshape

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

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

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中有什么东西可用于以这种方式重塑阵列吗?最好不要复制?

1 个答案:

答案 0 :(得分:3)

以下是更简单的方法:

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