我正在使用python连接C库。我有numpy中的数组,我使用数组的ctypes
属性传递给库。
在某些时候我需要为C库提供一个数组,这个数组应该是我所拥有的numpy数组a
的转置。 (另一种说法是C库不接受最内层维度的步幅)。但是,当我通过a.T
代替a
时,没有任何反应。
事实上,通过简单地交换步幅,numpy似乎做了某种懒惰的转换:
import ctypes
import numpy as np
a = np.zeros((2, 3))
a.ctypes.strides_as(ctypes.c_longlong)[:]
# returns [24, 8]
a.T.ctypes.strides_as(ctypes.c_longlong)[:]
# return [8, 24]
我的问题是,如何在内存中强制执行此转置?
修改
我注意到了
a.T + np.zeros(a.T.shape)
按照我想要的方式重新排序内存,但如果有更优雅明确的解决方案,我仍然希望听到它。
(另外,有趣的是,
a.T + np.zeros_like(a.T)
似乎不重新排序内存。)
答案 0 :(得分:1)
a.T
与a.transpose()
一样,只影响标题和返回视图。
您可以使用a.T.flags.owndata
检查它们,False
。
要实际转置数据,这是制作副本的最简单方法:a=a.T.copy()
。
实现这一目标是一项艰巨的任务。你可以这样做:
a=np.arange(6).reshape(2,3).copy()
print(a,a.flags,id(a),sep='\n')
a.ravel()[:]=a.T.ravel()
a.shape=a.T.shape
print(a,a.flags,id(a),sep=('\n'))
输出:
[[0 1 2]
[3 4 5]]
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
221212538640
[[0 3]
[1 4]
[2 5]]
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
221212538640
但是没有保证,因为你写了你读过的数据。在大型阵列上没有警告就可以失败。