这样才能更好地理解事情。这不是我需要解决的实际问题。一个cstringIO
对象应该模拟一个字符串、一个文件以及一个迭代器。它是否也模拟缓冲区?在任何情况下,理想情况下都应该能够构造一个numpy数组,如下所示
import numpy as np
import cstringIO
c = cStringIO.StringIO('\x01\x00\x00\x00\x01\x00\x00\x00')
#Trying the iterartor abstraction
b = np.fromiter(c,int)
# The above fails with: ValueError: setting an array element with a sequence.
#Trying the file abstraction
b = np.fromfile(c,int)
# The above fails with: IOError: first argument must be an open file
#Trying the sequence abstraction
b = np.array(c, int)
# The above fails with: TypeError: long() argument must be a string or a number
#Trying the string abstraction
b = np.fromstring(c)
#The above fails with: TypeError: argument 1 must be string or read-only buffer
b = np.fromstring(c.getvalue(), int) # does work
我的问题是它为什么会这样。在
实际出现的问题是:我有一个迭代器,它产生一个元组。我感兴趣的是从元组的一个组件生成numpy数组,尽可能少地复制和复制。我的第一个方法是继续将生成的元组的有趣组件写入StringIO对象,然后将其内存缓冲区用于数组。我当然可以使用getvalue()
,但我将创建并返回一个副本。什么是避免额外复制的好方法。在
由于
cStringIO
没有实现缓冲区接口,如果它的getvalue
返回数据的副本,那么在不复制的情况下无法获取其数据。在如果
getvalue
以字符串的形式返回缓冲区,而不进行复制,numpy.frombuffer(x.getvalue(), dtype='S1')
将给出一个引用字符串的(只读)numpy数组,而不附加副本。在
^{1}$np.fromiter(c, int)
和np.array(c, int)
不起作用的原因是cStringIO
在迭代时,一次返回一行,与文件类似:这样长的字符串不能转换为单个整数。在
^{pr2}$最好不要太担心复印,除非它真的是个问题。原因是,使用生成器并将其传递给
numpy.fromiter
中的额外开销实际上可能比构造一个列表并将其传递给numpy.array
所涉及的额外开销要大——与Python运行时开销相比,复制可能要便宜一些。在但是,如果问题出在内存上,那么一个解决方案是将这些项直接放入最终的Numpy数组中。如果事先知道大小,可以预先分配。如果大小未知,可以使用数组中的
.resize()
方法根据需要增大它。在问题似乎是纽比不喜欢被赋予字符而不是数字。请记住,在Python中,单个字符和字符串具有相同的类型-numpy必须在幕后进行某种类型检测,并将
'\x01'
作为一个嵌套序列。在另一个问题是
cStringIO
迭代它的行,而不是它的字符。在下面的迭代器可以解决这两个问题:
^{1}$像这样使用它(注意搜索!)公司名称:
^{pr2}$相关问题 更多 >
编程相关推荐