【发布时间】:2012-10-15 02:19:32
【问题描述】:
有几个类似的问题,但没有一个直接回答这个简单的问题:
我如何捕获命令输出并将该内容流式传输到 numpy 数组而不创建要读取的临时字符串对象?
所以,我想做的是:
import subprocess
import numpy
import StringIO
def parse_header(fileobject):
# this function moves the filepointer and returns a dictionary
d = do_some_parsing(fileobject)
return d
sio = StringIO.StringIO(subprocess.check_output(cmd))
d = parse_header(sio)
# now the file pointer is at the start of data, parse_header takes care of that.
# ALL of the data is now available in the next line of sio
dt = numpy.dtype([(key, 'f8') for key in d.keys()])
# i don't know how do make this work:
data = numpy.fromxxxx(sio , dt)
# if i would do this, I create another copy besides the StringIO object, don't I?
# so this works, but isn't this 'bad' ?
datastring = sio.read()
data = numpy.fromstring(datastring, dtype=dt)
我用 StringIO 和 cStringIO 试过,但 numpy.frombuffer 和 numpy.fromfile 都不接受。
使用 StringIO 对象我首先必须将流读入字符串,然后使用 numpy.fromstring,但我想避免创建中间对象(几千兆字节)。
如果我可以将 sys.stdin 流式传输到 numpy 数组中,对我来说另一种选择是,但这也不适用于 numpy.fromfile (需要实现搜索)。
是否有任何解决方法?我不能成为第一个尝试这个的人(除非这是一个 PEBKAC 案例?)
解决方案: 这是当前的解决方案,它是 unutbu 的指令如何使用 Popen 和 PIPE 和 eryksun 的提示使用 bytearray 的混合,所以我不知道该接受谁!? :S
proc = sp.Popen(cmd, stdout = sp.PIPE, shell=True)
d = parse_des_header(proc.stdout)
rec_dtype = np.dtype([(key,'f8') for key in d.keys()])
data = bytearray(proc.stdout.read())
ndata = np.frombuffer(data, dtype = rec_dtype)
我没有检查数据是否真的没有创建另一个副本,不知道如何。但是我注意到这比我以前尝试过的所有方法都快得多,非常感谢两位答案的作者!
2022 年更新: 我只是在没有 bytearray() 步骤的情况下尝试了上述解决方案步骤,并且效果很好。多亏了 Python 3?
【问题讨论】:
-
你考虑过numpy.fromiter吗?
-
您能否发布一个(简化的)示例,说明我们正在处理哪种函数(或输入)?
-
也许将
Popen与stdout=subprocess.PIPE一起使用(即没有与check_output一样的临时字符串),读入标题,然后将其余部分加载到bytearray以与np.frombuffer一起使用。 NumPy 数组将与bytearray共享相同的内存。 -
你的方法有效,@eryksun。将其放入答案以获得一些接受点。 ;)
标签: python numpy stdin stringio