2

私はいくつかの奇妙なログファイルを丸呑みして pandas.DataFrame に入れるPython スクリプトを持っているので、いくつかの統計分析を行うことができます。ログは 5 分間隔でのプロセスのスナップショットであるため、各ファイルを読み取るときに、最後のファイルから入力されたデータに対して新しい行をチェックして、以前と同じプロセスであるかどうかを確認します (この場合、既存のレコードの時間)。問題なく動作しますが、個々のログが 100,000 行を超えると驚くほど遅くなる可能性があります。

パフォーマンスをプロファイリングすると、目立ったものはほとんどありませんが、この単純な関数に多くの時間が費やされていることがわかります。これは基本的に、シリーズを前のログから持ち越された行と比較しています。

def carryover(s,df,ids):
    # see if pd.Series (s) matches any rows in pd.DataFrame (df) from the given indices (ids)
    for id in ids:
        r = df.iloc[id]
        if (r['a']==s['a'] and
            r['b']==s['b'] and
            r['c']==s['c'] and
            r['d']==s['d'] and
            r['e']==s['e'] and
            r['f']==s['f'] ):
            return id
    return None

andは短絡しているので、これはかなり効率的だと思います...しかし、もっと良い方法はありますか?

それ以外の場合、これをより速く実行するために他にできることはありますか? 結果のDataFrameはRAMに問題なく収まるはずですが、キャッシュなどが最適であることを確認するために設定する必要があるかどうかはわかりません。皆さんありがとう!

4

1 に答える 1

2

このように反復してルックアップするのは非常に遅いです (たとえ短絡しますが)、おそらく速度は s にヒットする可能性に依存します...

より「numpy」な方法は、配列全体でこの計算を行うことです。

equals_s = df.loc[ids, ['a', 'b', 'c', 'd', 'e', 'f']] == s.loc['a', 'b', 'c', 'd', 'e', 'f']
row_equals_s = equals_s.all(axis=1)

次に、これが True である最初のインデックスは次のidxmaxとおりです。

row_equals_s.idxmax()

速度が重要で、短絡が重要な場合は、関数を cython に書き直すことをお勧めします。これにより、numpy 配列を高速に反復処理できます。

于 2013-07-23T20:05:22.570 に答える