I am interfacing a C library with python. I have arrays in numpy that I pass to the library using the ctypes
attribute of the array.
At some point I need to provide an array to the C library, that is expected to be the transposed of the numpy array a
I have. (Another way of putting it is that the C library does not accept a stride for the inner-most dimension). However when I pass a.T
instead of a
, nothing happens.
Indeed it seems that numpy does some sort of lazy transposition by simply swapping the strides:
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]
My question is, how to enforce this transposition to happen in memory?
EDIT
I noticed that
a.T + np.zeros(a.T.shape)
reorders the memory like I want, but if there is a more elegant and explicit solution, I would still like to hear it.
(Also, interestingly,
a.T + np.zeros_like(a.T)
seems to not reorder memory).
a.T
, like a.transpose()
, just affect the header and return views.
You can check them with : a.T.flags.owndata
, wich is False
.
To actually transpose the data, the simplest way to make a copy : a=a.T.copy()
.
Making it in place is a harder task. You can do it this way :
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'))
Output :
[[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
But with no warranty, since you write on data you read. It can fails without warning on big arrays.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With