通过管道外部程序的输出将数据加载到numpy数组

时间:2016-12-23 02:28:48

标签: python numpy stdout

我有一个程序输出一个巨大的float32数组,前面是40个字节的标题。该程序写入stdout。

我可以将输出转储到文件中,在python中打开它,跳过标题的40个字节,然后使用numpy.fromfile()将其加载到numpy中。然而,这需要很多时间。

所以我想做的是通过读取生成它的程序的stdout将数组直接加载到numpy中。但是我很难搞清楚这一点。

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以memory-map该文件而不是全部阅读。这几乎不需要时间:

np.memmap(filename, np.float32, offset=40)

当然实际上从结果中读取数据需要一些时间,但可能会通过将I / O与计算交错来隐藏。

如果您确实不希望将数据写入磁盘,可以使用subprocess.Popen()stdout=subprocess.PIPE运行程序,并将生成的类似stdout文件的对象直接传递给{{ 1}}。

答案 1 :(得分:0)

非常感谢所有回复/评论的人。

我按照downshift的建议查看了他提供的链接......

并想出了以下内容:

nLayers=<Number of layers in program output>
nRows=<Number of rows in layer> 
nCols=<Number of columns in layer>
nBytes=<Number of bytes for each value>
noDataValue=<Value used to code no data in program output>
DataType=<appropriate numpy data type for values>

perLayer=nRows*nCols*nBytes

proc = sp.Popen(cmd+args, stdout = sp.PIPE, shell=True)
data=bytearray()
for i in range(0,nLayers):
   dump40=proc.stdout.read(40)
   data=data+bytearray(proc.stdout.read(perLayer))
ndata = np.frombuffer(data, dtype=DataType)
ndata[ndata == noDataValue]=np.nan
ndata.shape = (nLayers,nRows,nCols)

这里的关键是使用numpy.frombuffer,它使用相同的读缓冲区来创建darray,从而避免了必须在内存中复制数据。