我有缓冲,dtype,形状和步幅。我想创建一个Numpy ndarray,它重用缓冲区的内存。
有numpy.frombuffer
从缓冲区创建一维数组并重用内存。但是,我不确定我是否可以轻松安全地重塑它并设定步伐。
有numpy.ndarray
constructor可以引用缓冲区,但我不确定它是否会重用内存或是否会复制它(文档中不清楚)。
那么,numpy.ndarray
构造函数会按我的意愿执行吗?或者我可以使用什么呢?
好的,所以我现在想弄清楚numpy.ndarray
构造函数到底在做什么。代码是here。它使用PyArray_BufferConverter
转换缓冲区参数。然后它会调用PyArray_NewFromDescr_int
,可以看到here。如果数据在那里传递,它将fa->flags &= ~NPY_ARRAY_OWNDATA;
。
答案 0 :(得分:2)
我坚持使用frombuffer
,因为它直接用于此目的,并清楚地说明了你在做什么。这是一个例子:
In [58]: s0 = 'aaaa' # a single int32
In [59]: s1 = 'aaabaaacaaadaaae' # 4 int32s, each increasing by 1
In [60]: a0 = np.frombuffer(s0, dtype='>i4', count=1) # dtype sets the stride
In [61]: print a0
[1633771873]
In [62]: a1 = np.frombuffer(s, dtype='>i4', count=4)
In [63]: print a1
[1633771874 1633771875 1633771876 1633771877]
In [64]: a2 = a1.reshape((2,2)) # do a reshape, which also sets the strides
In [65]: print a2
[[1633771874 1633771875]
[1633771876 1633771877]]
In [66]: a2 - a0 # do some calculation with the reshape
Out[66]:
array([[1, 2],
[3, 4]], dtype=int32)
你有什么需要这样做吗?
答案 1 :(得分:2)
您可以使用任何一种方法 - 它们都不会生成副本:
s = 'aaabaaacaaadaaae'
a1 = np.frombuffer(s, np.int32, 4).reshape(2, 2)
a2 = np.ndarray((2, 2), np.int32, buffer=s)
print(a1.flags.owndata, a1.base)
# (False, 'aaabaaacaaadaaae')
print(a2.flags.owndata, a2.base)
# (False, 'aaabaaacaaadaaae')
答案 2 :(得分:2)
如@hpaulj的评论所述,您可以使用stride_tricks模块完成此操作。您需要np.frombuffer
和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)