从cStringIO对象生成Numpy数组并避免复制

2024-06-08 02:42:47 发布

您现在位置:Python中文网/ 问答频道 /正文

这样才能更好地理解事情。这不是我需要解决的实际问题。一个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(),但我将创建并返回一个副本。什么是避免额外复制的好方法。在


Tags: thenumpywithnp数组beargumentabove
2条回答

由于cStringIO没有实现缓冲区接口,如果它的getvalue返回数据的副本,那么在不复制的情况下无法获取其数据。在

如果getvalue以字符串的形式返回缓冲区,而不进行复制,numpy.frombuffer(x.getvalue(), dtype='S1')将给出一个引用字符串的(只读)numpy数组,而不附加副本。在


np.fromiter(c, int)np.array(c, int)不起作用的原因是cStringIO在迭代时,一次返回一行,与文件类似:

^{1}$

这样长的字符串不能转换为单个整数。在

^{pr2}$

最好不要太担心复印,除非它真的是个问题。原因是,使用生成器并将其传递给numpy.fromiter中的额外开销实际上可能比构造一个列表并将其传递给numpy.array所涉及的额外开销要大——与Python运行时开销相比,复制可能要便宜一些。在

但是,如果问题出在内存上,那么一个解决方案是将这些项直接放入最终的Numpy数组中。如果事先知道大小,可以预先分配。如果大小未知,可以使用数组中的.resize()方法根据需要增大它。在

问题似乎是纽比不喜欢被赋予字符而不是数字。请记住,在Python中,单个字符和字符串具有相同的类型-numpy必须在幕后进行某种类型检测,并将'\x01'作为一个嵌套序列。在

另一个问题是cStringIO迭代它的行,而不是它的字符。在

下面的迭代器可以解决这两个问题:

^{1}$

像这样使用它(注意搜索!)公司名称:

^{pr2}$

相关问题 更多 >

    热门问题