2

私はコーディングにかなり慣れておらず、バイナリファイルから信号を読み取っています。データは、複素数を構成する2つの4バイトフロートとして方向付けられます。これは、最大1500のエントリに対して繰り返されます。

forループを使用してデータを抽出し、複素数を配列に追加しています

for x in range(dimX):
    for y in range(dimY):
        complexlist=[]
        #2 floats, each 4 bytes, is one complex number
        trace=stream.readBytes(8*dimZ)
        #Unpack as list of floats
        floatlist=struct.unpack("f"*2*dimZ,trace)
        for i in range(0,len(floatlist)-1,2):
            complexlist.append(complex(floatlist[i],floatlist[i+1]))        
        data[x][y]=np.array(complexlist)

dimXが数千の場合、DimYは通常<30、dimZは<1500です。

しかし、これは大きなファイルでは非常に遅いです

トレース全体のバッファーを読み取り、複素数の配列に直接解凍する方法はありますか?

4

1 に答える 1

3

はいあります。n内部的には、numpyは複素数の配列を2nfloatの配列として表すため、Pythonの複素数型の手順をスキップできます。

これは、REPLからの簡単な例です。

>>> import numpy as np
>>> a = np.array([1.,2.,3.,4.])
>>> a
array([ 1.,  2.,  3.,  4.])
>>> a.dtype
dtype('float64')
>>> a.dtype = complex
>>> a
array([ 1.+2.j,  3.+4.j])
>>> 

dtypeただし、最初の配列に。以外の配列がある場合、これは機能しないことに注意してくださいfloat

>>> a = np.array([1,2,3,4])
>>> a
array([1, 2, 3, 4])
>>> a.dtype
dtype('int64')
>>> a.dtype = complex
>>> a
array([  4.94065646e-324 +9.88131292e-324j,
         1.48219694e-323 +1.97626258e-323j])
>>>

あなたの場合。必要なdtypeはnp.dtype('complex64')、各複素数が64ビット(2 * 4 * 8)であるためです。

for x in range(dimX):
    for y in range(dimY):
        #2 floats, each 4 bytes, is one complex number
        trace=stream.readBytes(8*dimZ)
        a = np.frombuffer(trace,dtype=np.dtype('complex64'))
        data[x][y] = a

それはあなたをかなりスピードアップするはずです。numpy.frombuffer()仕組みに関するREPLの例を次に示します。

>>> binary_string = struct.pack('2f', 1,2)
>>> binary_string
'\x00\x00\x80?\x00\x00\x00@'
>>> numpy.frombuffer(binary_string, dtype=np.dtype('complex64'))
array([ 1.+2.j], dtype=complex64)
>>> 

編集:私はの存在に気づいていませんでしたnumpy.frombuffer()。そのため、charの配列を作成してから、同じ効果を得るためにdtypeを変更していました。ありがとう@wim

編集2:

さらに速度を最適化する場合は、明示的なforループではなく、リスト内包表記を使用することでパフォーマンスが向上する可能性があります。

for x in range(dimX):
    data[x] = [np.frombuffer(stream.readBytes(8*dimZ), dtype=np.dtype('complex64')) for y in range(dimY)]

それでもレベルアップ:

data = [[np.frombuffer(stream.readBytes(8*dimZ), dtype=np.dtype('complex64'))
         for y in range(dimY)]
         for x in range(dimX)]
于 2013-03-06T10:57:05.280 に答える