2017-08-08 9 views
1

私は複数の列(c1 ... c8)と〜32 milの行を持つlarge-ish pandasデータフレームを持っています。データフレームはすでにc1によってソートされています。私はc1の特定の値を共有する行から他の列の値を取得したい。並べ替えられた列を使用してパンダのデータフレームから効率よく行を選択

何かしかし、これはそれが一致基準のために列全体をチェックするので、私は考えて非常に遅いことが判明し

keys = big_df['c1'].unique() 
red = np.zeros(len(keys)) 
for i, key in enumerate(keys): 
    inds = (big_df['c1'] == key) 
    v1 = np.array(big_df.loc[inds]['c2']) 
    v2 = np.array(big_df.loc[inds]['c6']) 
    red[i] = reduce_fun(v1,v2) 

のような(のみ関連している32万のうち10行があるかもしれませんが) 。 big_dfはc1でソートされており、キーはすべてのユニークなc1のリストにすぎないので、red []配列を得るための高速な方法があります(つまり、次のキーを持つ最初の行は前のキーは、キーの最後の行がキーと一致する最後の行であることがわかります。後続の行はすべて一致しないことが保証されているためです)。

おかげで、

イリヤ

編集:私は)何のためのユニークな()メソッドが生成されますが、私は基本的には、キー内のすべてのキーのreduce_funの値を(持っていたい、私は「ドンわかりません特に彼らがどのような順序であるかに注意してください(おそらく最も簡単な順序は、c1が既にソートされている順序です)。

Edit2:私は少しコードを再構成しました。基本的に、indsを構築する効率的な方法はありますか? big_df ['c1'] ==キーはデータ内の合計時間の75.8%を占めますが、v1を作成する際にv2はラインプロファイラに従って21.6%をとります。

+0

パンダは、データベースの意味でのインデックス付き行アクセスを提供しません。シーケンシャルアクセスは唯一の選択肢ですが、データフレームを配列やリストのリストに変換して検索しない限り、私は恐れます。しかし、変換操作は元の選択自体と同じくらい時間がかかります。 – DyZ

答えて

4

リストではなく、各項目にキー入力された縮小値を保持する辞書をc1に選択しました。

red = {key: reduce_func(frame['c2'].values, frame['c7'].values) 
     for key, frame in df.groupby('c1')} 
+2

これは私のコードより約250倍高速です。ありがとうございました! – Ilya

2

groupbyはリストの理解度はどうですか?これは、すでにc1でソートされてDataFrame与え、特に効率的でなければなりません:

編集は:groupbyはタプルを返すことを忘れました。おっとっと!

red = [reduce_fun(g['c2'].values, g['c6'].values) for i, g in big_df.groupby('c1', sort=False)] 

(23000万ランダム行の秒と平凡なreduce_fun〜)私にとってはかなり早くて一気飲みするようです。

+0

これは、df.groupbyがタプル(key、df)を返すので、g [1] ['c2']などでなければならないという小さな修正でうまくいくようです。 – Ilya

+0

おっと!それを指摘してくれてありがとう、@イリーヤ! – PaSTE

関連する問題