I have a buffer, dtype, shape and strides. I want to create a Numpy ndarray which reuses the memory of the buffer.
There is numpy.frombuffer
which creates a 1D array from a buffer and reuses the memory. However, I'm not sure if I can easily and safely reshape it and set the strides.
There is the numpy.ndarray
constructor which can refer to a buffer but I'm not sure if it will reuse the memory or if it will copy it (it's not clear from the documentation).
So, will the numpy.ndarray
constructor do what I want? Or what can I use instead?
Ok, so I'm trying to figure out myself now what the numpy.ndarray
constructor is really doing. The code is here. It uses PyArray_BufferConverter
to convert the buffer argument. Then it will call PyArray_NewFromDescr_int
which can be seen here. If data is passed in there, it will fa->flags &= ~NPY_ARRAY_OWNDATA;
.
An ndarray is a (usually fixed-size) multidimensional container of items of the same type and size. The number of dimensions and items in an array is defined by its shape , which is a tuple of N non-negative integers that specify the sizes of each dimension.
The strides of an array tell us how many bytes we have to skip in memory to move to the next position along a certain axis. For example, we have to skip 4 bytes (1 value) to move to the next column, but 20 bytes (5 values) to get to the same position in the next row.
As mentioned in the comment by @hpaulj, you can accomplish this using the stride_tricks module. You need both np.frombuffer
and np.lib.stride_tricks.as_strided
:
In [1]: import numpy as np
In [2]: x = np.random.random((3, 4)).astype(dtype='f4')
In [3]: buffer = x.data
In [4]: dtype = x.dtype
In [5]: shape = x.shape
In [6]: strides = x.strides
In [7]: xx = np.frombuffer(buffer, dtype)
In [8]: xx = np.lib.stride_tricks.as_strided(xx, shape, strides)
In [9]: x
Out[9]:
array([[ 0.75343359, 0.20676662, 0.83675659, 0.99904215],
[ 0.37182721, 0.83846378, 0.6888299 , 0.57195812],
[ 0.39905572, 0.7258808 , 0.88316005, 0.2187883 ]], dtype=float32)
In [10]: xx
Out[10]:
array([[ 0.75343359, 0.20676662, 0.83675659, 0.99904215],
[ 0.37182721, 0.83846378, 0.6888299 , 0.57195812],
[ 0.39905572, 0.7258808 , 0.88316005, 0.2187883 ]], dtype=float32)
In [11]: x.strides
Out[11]: (16, 4)
In [12]: xx.strides
Out[12]: (16, 4)
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