同様の質問がいくつかありますが、この単純な質問に直接答えるものはありません。
一時的な文字列オブジェクトを作成せずに、コマンド出力をキャッチし、そのコンテンツを 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 の指示と PIPE で Popen を使用する方法と、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 のおかげでしょうか。