Performing an in-memory transfer of a numpy array
I am interacting with a C library from python. I have arrays in numpy that I pass to the library using the ctypes
array attribute .
At some point, I need to provide an array in the C library that is expected to be carried over from the numpy array a
I have. (Another way to say is that the C library does not take a step for the innermost dimension). However, when I pass a.T
instead a
, nothing happens.
Indeed, it seems that numpy is doing some kind of lazy transposition, just replacing the steps:
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 do I get this transposition to happen in memory?
EDIT
I noticed that
a.T + np.zeros(a.T.shape)
reorders memory as I want, but if there is a more elegant and explicit solution, I would love to hear it anyway.
(Also interesting,
a.T + np.zeros_like(a.T)
doesn't seem to change memory order).
source to share
a.T
for example a.transpose()
just affect the title and return views. You can check them out:, a.T.flags.owndata
<< 23>.
To actually transfer the data, the easiest way to make a copy of: a=a.T.copy()
.
Making it in place is more challenging. You can do it like this:
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 without any guarantees, since you are writing the data you are reading. It can crash without warning on large arrays.
source to share