2016-08-26 10 views
2

私は約10 000行の2つのデータフレームを持っています。それらは以下のaとbと似ていますが、より多くの行があります。Pythonでforループをより高速に置き換える方法

a 
Out[9]: 
    end start 
0 4.0  3 
1 5.5  5 
2 7.5  7 
3 9.5  9 
4 11.5  11 
5 15.0  14 
6 18.0  17 
7 21.0  20 
8 26.0  25 
9 31.0  30 

b 
Out[10]: 
     status 
moment  
8.0   o 
10.0  o 
14.5  o 
16.0  o 
19.0  o 
27.0  o 
28.0  o 
30.5  o 
35.0  o 
40.0  o 
50.0  o 

データフレームbのすべての瞬間を、データフレームaの終わりと開始の間に属させる必要があります。

私はそのためにループ用に開発しましたが、小さなデータフレームでうまく動作します。

ここで、開始と終了の間にモーメントがあるとき、ループがo - > mに置き換わっている様子を見ることができます。

n [12]: b 
Out[12]: 
     status 
moment  
8.0   o 
10.0  o 
14.5  m 
16.0  o 
19.0  o 
27.0  o 
28.0  o 
30.5  m 
35.0  o 
40.0  o 
50.0  o 

私はそれが合理的な期間内にそれ以上の結果を得ることができない巨大なデータフレーム(データフレームでは10以上000行)でそれを使用するようにしてください。

私のforループをより速く、より長いデータフレームに適したものにする方法がありますか?

+0

は、同じ長さの両方のデータフレームはありますか? – shivsn

+0

'o'を 'm'に変更すると、最小限の改善が内側のループから抜け出すので、あなたがマッチすると、「b」を見続ける必要はありません。 – jwpfox

答えて

0

解決方法は実行時間でO(n^2)です。すべてのデータフレームがソートされている限り、DFの場合は除算と征服の方法を使ってO(nlogn)にすることができます。コーディングは簡単ではありませんが、それを見て、D &のCのメソッドを理解し、それを再帰関数として記述する必要があります。私はあなたがO(nlogn)ので、各要素のO(logn)であるこの問題のアルゴリズムBinarySearchを作成することができると思います。

私が間違っていて、DFがソートされていないが、この種の検索を何度もしなければならない場合は、最初にソートすることをお勧めします。ソートはD & Cで行うこともできます。普通はMergeSortと呼ばれ、そのO(nlogn)も同様です。ここで

1

は、ベクタースキャンを回避しませんが、ベクトル化されforループ、なしのオプションです:

b[b.index.map(lambda m: ((m > a.start) & (m < a.end)).any())] = "m" 

b 

# status 
# moment  
# 8.0 o 
# 10.0 o 
# 14.5 m 
# 16.0 o 
# 19.0 o 
# 27.0 o 
# 28.0 o 
# 30.5 m 
# 35.0 o 
# 40.0 o 
# 50.0 o 
関連する問題