Python numpy.getbuffer和numpy.frombuffer

Python numpy.getbuffer和numpy.frombuffer,python,numpy,buffer,Python,Numpy,Buffer,我正试图了解PEP3118的numpy实现。缓冲区访问在numpy中究竟是如何工作的 >>> p = numpy.getbuffer(numpy.arange(10)) >>> p <read-write buffer for 0x1003e5b10, size -1, offset 0 at 0x1016ab4b0> >>> numpy.frombuffer(p) array([ 0.00000000e+000, 4.94

我正试图了解PEP3118的numpy实现。缓冲区访问在numpy中究竟是如何工作的

>>> p = numpy.getbuffer(numpy.arange(10))
>>> p
<read-write buffer for 0x1003e5b10, size -1, offset 0 at 0x1016ab4b0>
>>> numpy.frombuffer(p)
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
     1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
     2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
     4.44659081e-323])

看起来缓冲区正在初始化为全零,然后我可以写入。我期望的功能是能够使用getbuffer将数组(使用arange或asarray)直接构建到缓冲区。这不可能吗?

您有一个简单的
dtype
问题。使用创建的缓冲区

np.getbuffer(np.arange(10))
有一个
dtype=int
,因为
np.arange
默认使用
dtype=int

然后,当您尝试使用

np.frombuffer(p)
实际上,您正在使用
np.frombuffer
dtype=float
默认值。相反,使用

np.frombuffer(p, dtype=int)
等等,你明白了吗

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

让我对皮埃尔的杰出作品补充几点意见

只有在必须对
ndarray
进行切片时,才需要
getbuffer
:可以通过
data
属性检索与整个数组关联的python缓冲区对象

>>> import numpy as np
>>> a = np.arange(10)
>>> a.data == np.getbuffer(a)
True
相反,您不需要将实际的缓冲区对象传递给
frombuffer
函数,每个公开
buffer
接口的对象都是好的

>>> np.frombuffer(a, a.dtype)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.frombuffer(a)
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
         1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
         2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
         4.44659081e-323])
>>> import array
>>> c = array.array('i', range(10))
>>> np.frombuffer(c, np.int32)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
>>> np.frombuffer(c)
array([  2.12199579e-314,   6.36598737e-314,   1.06099790e-313,
         1.48539705e-313,   1.90979621e-313])
解码缓冲区对象时,必须知道正确的
dtype
,如上面的示例所示。更准确地说,缓冲区对象没有
dtype
:它们只是一个二进制数据流。相反,
ndarray
对象有一个
dtype
,它指示如何解释底层二进制数据


回答您的问题:每个numpy
ndarray
都公开缓冲区接口。您可以通过
data
描述符或
getbuffer
函数访问缓冲区或缓冲区的一部分。您可以通过
frombuffer
函数从暴露缓冲区接口的对象创建
ndarray
。由于缓冲区(与
ndarrays
相反)没有
dtype
信息,因此您应该始终明确指定如何通过
dtype
参数对
frombuffer

缓冲区进行交互,这是Pierre答案的精彩补充。额外的细节是非常感谢。
>>> np.frombuffer(a, a.dtype)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.frombuffer(a)
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
         1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
         2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
         4.44659081e-323])
>>> import array
>>> c = array.array('i', range(10))
>>> np.frombuffer(c, np.int32)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
>>> np.frombuffer(c)
array([  2.12199579e-314,   6.36598737e-314,   1.06099790e-313,
         1.48539705e-313,   1.90979621e-313])