2016-09-30 17 views
3

Iは、以下パンダのデータフレームを有する:pandas DataFrameの複数の列を「間隔」に一致させるにはどうすればよいですか?

import pandas as pd 
df = pd.DataFrame('filename.csv') 
print(df) 

order start end value  
1  1342 1357 category1 
1  1459 1489 category7 
1  1572 1601 category23 
1  1587 1599 category2 
1  1591 1639 category1 
.... 
15  792  813 category13 
15  892  913 category5 
.... 

したがって、order列があるが、その後多くの行それぞれ、各行のためstartからend範囲/間隔を包含する。各行に特定のvalue(カテゴリ1、カテゴリ2など)のラベルが付けられています

今、別のデータフレームkey_dfがあります。

import pandas as pd 
key_df = pd.DataFrame(...) 
print(key_df) 

order start end value  
1  1284 1299 category4 
1  1297 1309 category9 
1  1312 1369 category3 
1  1345 1392 category29 
1  1371 1383 category31 
.... 
1  1471 1501 category31 
... 

私の目標はkey_dfデータフレームを取るとの間隔は、元のデータフレームdf内の行のいずれかに一致start:endかどうかをチェックすることです:それは、基本的にはまったく同じ形式です。そうであれば、dfのこの行にはkey_dfデータフレームのvalueという値が付けられます。あなたはkey_dfを見ればため

order start end value  key_value 
1  1342 1357 category1 category29 
1  1459 1489 category7 category31 
.... 

これは、期間中に落ちる1::1345-1392間隔で行

1  1345 1392 category29 

です:

上記の例では、データフレームdfはこのように終わるだろう1::1342-1357オリジナルdfです。同様に、key_df行:

1  1471 1501 category31 

dfの2行目に対応:

1  1459 1489 category7 category31 

私は

(1)パンダ

でこのタスクを実行するかどうかは全くわからないんだけど

(2)パンダでこれを効率的にスケールする方法

if文で始めることができます。

if df.order == key_df.order: 
    # now check intervals...somehow 

しかし、これはデータフレーム構造を利用していません。 1つは間隔などで確認する必要があります。(df.start =< key_df.start) && (df.end => key_df.end)

私は立ち往生しています。パンダの「インターバル」で複数の列を照合する最も効率的な方法は何ですか?

答えて

1

あなたはboolean indexingmergeを使用することができます(この条件が満たされるならば、簡単な新しい列をされて作成)が、DataFramesが大きい場合は、スケーリングには問題がある:

df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) 
df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
df1 = pd.merge(df, df1, on=['order','start','end', 'value'], how='left') 
print (df1) 
    order start end  value start_key end_key value_key 
0  1 1342 1357 category1  1345.0 1392.0 category29 
1  1 1342 1357 category1  1371.0 1383.0 category31 
2  1 1342 1357 category1  1471.0 1501.0 category31 
3  1 1459 1489 category7  1471.0 1501.0 category31 
4  1 1572 1601 category23  NaN  NaN   NaN 
5  1 1587 1599 category2  NaN  NaN   NaN 
6  1 1591 1639 category1  NaN  NaN   NaN 
7  15 792 813 category13  NaN  NaN   NaN 
8  15 892 913 category5  NaN  NaN   NaN 
:コメントによって

df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) 
df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
print (df1) 
    order start end  value start_key end_key value_key 
3  1 1342 1357 category1  1345.0 1392.0 category29 
4  1 1342 1357 category1  1371.0 1383.0 category31 
5  1 1342 1357 category1  1471.0 1501.0 category31 
11  1 1459 1489 category7  1471.0 1501.0 category31 

EDIT

+0

ここでエラーが発生しました。与えられた行に 'value_key'がない場合、これは破棄されます。私たちの目的のために、 'df'のすべての行は良いです---どれも破棄されるべきではありません。指定された行に「value_key」が適用されない場合(つまり、その区間に収まらない場合)、「NaN」を記録する必要があります。 – ShanZhengYang

+0

私のコードに 'left merge'を追加する必要がありますか? df1 = pd.merge(df、df1、on = ['order'、 'start'、 'end'、 'value']、how = 'left') '? – jezrael

+0

答えをありがとう。私は、これが100 MB前後のデータフレームに対してスケーラブルではないことを言及する必要があります。私は 'MemoryError'を取得します。これをよりスケーラブルにする方法はありますか?マージの代わりに、多くのforループ?これはエラーです: 'ファイル" pandas/src/join.pyx "、187行目、pandas.algos.full_outer_join''(pandas/algos.c:61680) ' 'ファイル "pandas/src/join.pyx" 、line 196、 ' ' pandas.algos._get_result_indexer(pandas/algos.c:61978) ' ' MemoryError' – ShanZhengYang

関連する問題