【发布时间】:2016-12-23 02:28:48
【问题描述】:
我有一个程序,它输出一个巨大的 float32 数组,前面有一个 40 字节的标头。程序写入标准输出。
我可以将输出转储到一个文件中,在 python 中打开它,跳过标头的 40 个字节,然后使用 numpy.fromfile() 将其加载到 numpy 中。但是,这需要很多时间。
所以我想做的是通过读取生成它的程序的标准输出将数组直接加载到 numpy 中。但是我很难弄清楚这一点。
谢谢!
【问题讨论】:
我有一个程序,它输出一个巨大的 float32 数组,前面有一个 40 字节的标头。程序写入标准输出。
我可以将输出转储到一个文件中,在 python 中打开它,跳过标头的 40 个字节,然后使用 numpy.fromfile() 将其加载到 numpy 中。但是,这需要很多时间。
所以我想做的是通过读取生成它的程序的标准输出将数组直接加载到 numpy 中。但是我很难弄清楚这一点。
谢谢!
【问题讨论】:
您可以memory-map 文件而不是全部阅读。这几乎不需要时间:
np.memmap(filename, np.float32, offset=40)
当然,实际从结果中读取数据需要一些时间,但可能会通过将 I/O 与计算交错来隐藏。
如果您真的不想将数据写入磁盘,您可以使用subprocess.Popen() 以stdout=subprocess.PIPE 运行您的程序,并将生成的stdout 类文件对象直接传递给numpy.fromfile()。
【讨论】:
非常感谢所有回复/评论的人。
我按照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,它使用相同的读取缓冲区来创建数组,从而避免了在内存中复制数据。
【讨论】: