2016-11-02 9 views
1

インデックスとしてID番号を使用している大きなデータセットがあります。私が処理を始める前に、いくつかの重複IDを扱う必要がありますが、複数の基準に基づいて行う必要があります。基本的にの各IDの重複エントリの中から最高のエントリを作成します。重複するパンダインデックスを複数の条件でドロップする

この例では、まず、最新の年の複製を取得して、id 1を一意にします。しかし、ID 3はまだので、私はそれが次の条件に行きたい、左の2つの値を持っている - この場合には、我々は最大のvalを言うよ:

import pandas as pd 
data = {'id':[1, 1, 2, 3, 3, 3], 'year':[2001, 2002, 2002, 2001, 2002, 2002], 'val':[7, 8, 9, 17, 11, 12]} 
df = pd.DataFrame(data).set_index('id') 

dups = df[df.index.duplicated(keep=False)] 

for id in dups.index.unique(): 
    current = dups.loc[id] 
    max_yr = current['year'].max() 
    #continue to process using multiple conditionals inside the loop 

結果がこれであるところ:

val year 
id 
1  7 2001 
1  8 2002 
2  9 2002 
3 17 2001 
3 11 2002 
3 12 2002 
それは作品

val year 
id 
1  8 2002 
2  9 2002 
3 12 2002 

が、それは非常に非効率的だとベクトル化または少なくともより良い方法これを実現するために存在しなければならないような気がします:

はこれにオンにします。 groupbyを組み込むこともできますが、私はグループをループすることなく、これをどうやってやるのかまだ分かりません。

+0

あなたは 'df.groupby(level = 0).max()'の後にいますか? – MaxU

+0

いいえ、複数の基準を考慮して複製を削除する必要があり、すべてのIDに対して1つの*ベスト*エントリが残っています。 – Jeff

答えて

1

アイデアは、最高のマッチを決定する複合カラムを追加することです。たとえば、最初の基準がmax(year)で、2番目がmax(val)の場合は、それらを組み合わせてtupleとし、その列の最大値を取ることができます。いくつかの基準がmin(X)の場合は、-Xをタプルに追加できます。 (tuples are compared element by element

import pandas as pd 
data = {'id':[1, 1, 2, 3, 3, 3], 'year':[2001, 2002, 2002, 2001, 2002, 2002], 'val':[7, 8, 9, 17, 11, 12]} 
df = pd.DataFrame(data).set_index('id') 
df['year_val'] = df.apply(lambda row: (row.year, row.val), axis=1) 
df.reset_index().groupby('id').apply(
    lambda df: df[df['year_val'] == df['year_val'].max()]).drop(
    ['year_val'], axis=1).set_index('id') 

    val year 
id   
1  8 2002 
2  9 2002 
3 12 2002   
+0

ああ、タプルトリックはこれには完璧です。ありがとう、私は一般的なPythonの機能を認識していませんでした。 – Jeff

+0

@ JeffL。うれしい! –