强制执行numpy数组的内存中转置

时间:2017-07-10 09:34:27

标签: python numpy ctypes

我正在使用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)

似乎重新排序内存。)

1 个答案:

答案 0 :(得分:1)

a.Ta.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

但是没有保证,因为你写了你读过的数据。在大型阵列上没有警告就可以失败。