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).

+3


source to share


1 answer


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.

+1


source







All Articles