给定一个字节缓冲区,dtype,形状和步幅,如何创建Numpy ndarray



我有一个缓冲区、dtype、形状和步幅。我想创建一个Numpy ndarray,它重用缓冲区的内存。

存在CCD_ 1,它从缓冲区创建1D阵列并重用存储器。然而,我不确定我是否能轻松、安全地重塑它并迈出步伐。

有一个numpy.ndarray构造函数可以引用缓冲区,但我不确定它是否会重用内存或复制内存(文档中不清楚)。

那么,numpy.ndarray构造函数会执行我想要的操作吗?或者我可以用什么代替?


好的,我现在试着弄清楚numpy.ndarray构造函数到底在做什么。代码在这里。它使用PyArray_BufferConverter来转换缓冲区参数。然后它将调用PyArray_NewFromDescr_int,可以在这里看到。如果数据在那里传递,它将fa->flags &= ~NPY_ARRAY_OWNDATA;

正如@hpaulj的评论中所提到的,您可以使用stride_ticks模块来实现这一点。您需要np.frombuffernp.lib.stride_tricks.as_strided:

从NumPy数组收集数据

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

重新创建NumPy数组

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)

我会坚持使用numpy.frombuffer0,因为它直接用于此目的,并使您清楚地了解自己在做什么。这里有一个例子:

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)

有什么你需要的而这不起作用吗?

您可以使用任何一种方法-它们都不会生成副本:

s = b'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.tostring())
# (False, b'aaabaaacaaadaaae')
print(a2.flags.owndata, a2.base)
# (False, b'aaabaaacaaadaaae')

请注意,这两个阵列都不能就地修改,因为它们由只读存储器支持:

a1[:] = 0  # ValueError: assignment destination is read-only

相关内容

  • 没有找到相关文章