2

1e8の長さ(1億要素)の1-D時系列があります。Dropboxで使用しているデータへのリンクは次のとおりです(ファイルは382 MBです。)

アップデート

memory_profilingに基づいて、エラーは行で発生します

data[absolute(data-dc)< m*std(data)]=dc.

具体的には、操作によってabsolute(data-dc)すべてのメモリが消費されます。Data上記のとおりでdcあり、定数です。おそらくこれは微妙な構文エラーですか?

外れ値とアーティファクトを削除し、それらの値を中央値に置き換えたいと思います。私は次の関数でそれをやろうとしています。

 from numpy import *

 from sys import argv

 from scipy.io import savemat
 from scipy.stats import scoreatpercentile

 def reject_outliers(data,dc,m=3):
      data[data==0] = dc
      data[bp.absolute(data-dc) < m*np.std(data)] = dc
      return data

 def butter_bandpass(lowcut,highcut,fs,order=8):
    nyq = 0.5*fs
    low = lowcut/nyq
    high = highcut/nyq

    b,a= butter(order, [low, high], btype='band')
    return b,a

 def butter_bandpass_filter(data,lowcut,highcut,fs,order=8):
    b,a = butter_bandpass(lowcut,highcut,fs,order=order)
    return lfilter(b,a,data) 

 OFFSET = 432
 filename = argv[1]
 outname = argv[2]  

 print 'Opening '+ filename
 with open(filename,'rb') as stream:
      stream.seek(OFFSET)
      data=fromfile(stream,dtype='int16')
 print 'Removing Artifacts, accounting for zero-filling'
 dc = median(data)
 data = reject_outliers(data,dc)

 threshold = scoreatpercentile(absolute(data),85)   
 print 'Filtering and Detrending'
 data = butter_bandpass_filter(data,300,7000,20000)
 savemat(outname+'.mat',mdict={'data':data})

1つのファイルでこれを呼び出すと、4GBのRAMと3GBの仮想メモリが消費されます。作成したスクリプトをステップ実行したので、この関数の2行目であると確信しています。このスクリプトは、常にこの部分でハングします。(OS XのFinderで)利用可能なハードドライブのスペースが秒単位で急減しているのを見ることができます。

時系列はそれを説明するのに十分な長さではありません。の2行目の何が問題になっていreject-outliersますか?

4

3 に答える 3

5

100,000,000のランダムなフロートを生成し、あなたが説明したのと同じインデックスを作成しました。メモリ使用量は、全体を通してギガバイトをはるかに下回りました。あなたが私たちに話していないことをあなたのコードは他に何をしていますか?優れたmemory_profilerを介してコードを実行してみてください。


編集:memory_profilerのコードと出力を追加しました:

from numpy.random import uniform
import numpy

@profile
def go(m=3):
    data = uniform(size=100000000)
    dc = numpy.median(data)
    data[numpy.absolute(data-dc) < m*numpy.std(data)] = dc
    return data

if __name__ == '__main__':
    go()

出力:

Filename: example.py

Line #    Mem usage    Increment   Line Contents
================================================
     3                             @profile
     4     15.89 MB      0.00 MB   def go(m=3):
     5    778.84 MB    762.95 MB    data = uniform(size=100000000)
     6    778.91 MB      0.06 MB    dc = numpy.median(data)
     7    874.34 MB     95.44 MB    data[numpy.absolute(data-dc) < m*numpy.std(data)] = dc
     8    874.34 MB      0.00 MB    return data

ご覧のとおり、100Mフロートはそれほど多くのメモリを消費しません。

于 2013-02-04T14:26:46.707 に答える
4

データと変更された@mbatchkarovのコードの結果:

$ python mbatchkarov.py 
Filename: mbatchkarov.py

Line #    Mem usage    Increment   Line Contents
================================================
     5                             @profile
     6     15.74 MB      0.00 MB   def go(m=3):
     7     15.74 MB      0.00 MB       header_size = 432
     8     15.74 MB      0.00 MB       with open('ch008.ddt', 'rb') as file:
     9     15.75 MB      0.00 MB           file.seek(header_size)
    10    380.10 MB    364.36 MB           data = np.fromfile(file, dtype=np.int16) # 2 bytes per item                                                             
    11    380.20 MB      0.10 MB       dc = np.median(data)
    12                             
    13                                 # data[np.absolute(data - dc) < m*np.std(data)] = dc                                                                        
    14                                 # `data - dc` => temporary array 8 bytes per item                                                                           
    15    744.56 MB    364.36 MB       t = data.copy()
    16    744.66 MB      0.09 MB       t -= dc
    17    744.66 MB      0.00 MB       np.absolute(t, t)
    18    926.86 MB    182.20 MB       b = t < m*np.std(data) # boolean => 1 byte per item                                                                         
    19    926.87 MB      0.01 MB       data[b] = dc
    20    926.87 MB      0.00 MB       return data

data - dc数倍のメモリが必要になります。2億アイテムxアイテムあたり8バイト。つまり、data - dcブロードキャストのために1つまたは2つの一時的な二重配列が作成されます。これを回避するには、明示的なコピーを作成し、インプレースでサブ構造化します。

t = data.copy() # 200M items x 2 bytes per item
t -= dc

memory_profiler一時配列のメモリが表示されていないようです。プログラムの最大メモリは約3GBです。

于 2013-02-04T15:36:05.907 に答える
3

Memory_profilerは、指定された行が実行された後のPython仮想マシンの状態を行のメモリとして使用します。したがって、1行内で作成および破棄された配列は、プロファイルに表示されません。

@mbatchkarovの例をとると、「data [numpy.absolute(data-dc)<m * numpy.std(data)] = dc」という行を小さなチャンクに展開して、一時配列がメモリにどのように影響するかを確認できます。

from numpy.random import uniform
import numpy

@profile
def go(m=3):
    data = uniform(size=100000000)
    dc = numpy.median(data)
    t1 = data-dc
    t2 = numpy.absolute(t1) < m*numpy.std(data)
    data[t2] = dc
    return data

if __name__ == '__main__':
    go()

これは

$ python -m memory_profiler t1.py 
Filename: t1.py

Line #    Mem usage    Increment   Line Contents
================================================
     4                             @profile
     5     16.61 MB      0.00 MB   def go(m=3):
     6    779.56 MB    762.95 MB       data = uniform(size=100000000)
     7    779.62 MB      0.06 MB       dc = numpy.median(data)
     8   1542.57 MB    762.95 MB       t1 = data-dc
     9   1637.99 MB     95.42 MB       t2 = numpy.absolute(t1) < m*numpy.std(data)
    10   1638.00 MB      0.02 MB       data[t2] = dc
    11   1638.00 MB      0.00 MB       return data

ここで、「data-dc」命令がメモリレイアウトを複製していることは明らかです。これを回避するには、減算をインプレースで実行します。つまり、「t1 =data--dc」を「data-=dc」に置き換えます。

$ python -m memory_profiler t1.py 
Filename: t1.py

Line #    Mem usage    Increment   Line Contents
================================================
     4                             @profile
     5     16.61 MB      0.00 MB   def go(m=3):
     6    779.56 MB    762.95 MB       data = uniform(size=100000000)
     7    779.62 MB      0.06 MB       dc = numpy.median(data)
     8    779.63 MB      0.01 MB       data -= dc
     9    875.05 MB     95.42 MB       t2 = numpy.absolute(data) < m*numpy.std(data)
    10    875.07 MB      0.02 MB       data[t2] = dc
    11    875.07 MB      0.00 MB       return data

ご覧のとおり、「data-=dc」はメモリをほとんど増加させません。

于 2013-02-05T08:46:48.343 に答える