有没有比 array.transpose.copy() 更快的方法来物理转置大型 2D numpy 矩阵?是否有任何例程可以有效地使用内存?
最佳答案
可能值得看看转置的作用,这样我们就可以清楚您所说的“物理转置”的含义。
从一个小的 (4,3) 数组开始:
In [51]: arr = np.array([[1,2,3],[10,11,12],[22,23,24],[30,32,34]])
In [52]: arr
Out[52]:
array([[ 1, 2, 3],
[10, 11, 12],
[22, 23, 24],
[30, 32, 34]])
它存储在 1d 数据缓冲区中,我们可以使用 ravel
显示它:
In [53]: arr.ravel()
Out[53]: array([ 1, 2, 3, 10, 11, 12, 22, 23, 24, 30, 32, 34])
和 strides
告诉它以 8 个字节为单位步进,以 24 个字节为单位步进(3*8):
In [54]: arr.strides
Out[54]: (24, 8)
我们可以用“F”顺序来解释 - 这是沿着行向下:
In [55]: arr.ravel(order='F')
Out[55]: array([ 1, 10, 22, 30, 2, 11, 23, 32, 3, 12, 24, 34])
[53] 是一个 View
,而 [55] 是一个副本。
现在转置:
In [57]: arrt=arr.T
In [58]: arrt
Out[58]:
array([[ 1, 10, 22, 30],
[ 2, 11, 23, 32],
[ 3, 12, 24, 34]])
这是一个 View
;我们可以遍历 [53] 数据缓冲区,以 8 字节为步长向下移动。使用 arrt
进行计算基本上与使用 arr
一样快。通过strided
迭代,顺序“F”与顺序“C”一样快。
In [59]: arrt.strides
Out[59]: (8, 24)
原始订单:
In [60]: arrt.ravel(order='F')
Out[60]: array([ 1, 2, 3, 10, 11, 12, 22, 23, 24, 30, 32, 34])
但是进行“C”拆解会创建一个副本,与[55]相同
In [61]: arrt.ravel(order='C')
Out[61]: array([ 1, 10, 22, 30, 2, 11, 23, 32, 3, 12, 24, 34])
复制转置会生成一个按“C”顺序转置的数组。这是您的“物理转置”:
In [62]: arrc = arrt.copy()
In [63]: arrc.strides
Out[63]: (32, 8)
像[61]那样 reshape 转置确实会生成一个副本,但通常我们不需要显式地生成副本。我认为这样做的唯一原因是为了避免在以后的计算中产生多个冗余副本。
关于python - 物理转置大型非方 numpy 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62505938/