web-dev-qa-db-ja.com

pandas重複したデータを持つデータフレーム内の、年ごとのグループ、売上列によるランク付け

私は年のランクを作成したいと思います(したがって、2012年では、マネージャーBは1です。2011年には、マネージャーBが再び1です)。私はしばらくの間pandasランク関数と格闘し、forループに頼りたくありません。

s = pd.DataFrame([['2012','A',3],['2012','B',8],['2011','A',20],['2011','B',30]], columns=['Year','Manager','Return'])

Out[1]:     
   Year Manager  Return    
0  2012       A       3    
1  2012       B       8    
2  2011       A      20    
3  2011       B      30

私が持っている問題は追加のコードにあります(これは以前に関連があるとは思わなかった):

s = pd.DataFrame([['2012', 'A', 3], ['2012', 'B', 8], ['2011', 'A', 20], ['2011', 'B', 30]], columns=['Year', 'Manager', 'Return'])
b = pd.DataFrame([['2012', 'A', 3], ['2012', 'B', 8], ['2011', 'A', 20], ['2011', 'B', 30]], columns=['Year', 'Manager', 'Return'])

s = s.append(b)
s['Rank'] = s.groupby(['Year'])['Return'].rank(ascending=False)

raise Exception('Reindexing only valid with uniquely valued Index '
Exception: Reindexing only valid with uniquely valued Index objects

何か案は?
これは私が使用している実際のデータ構造です。インデックスの再作成で問題が発生しています。

17
Ben

Yearでグループ化し、Returnsを降順にランク付けしたいようです。

import pandas as pd
s = pd.DataFrame([['2012', 'A', 3], ['2012', 'B', 8], ['2011', 'A', 20], ['2011', 'B', 30]],
                 columns=['Year', 'Manager', 'Return'])
s['Rank'] = s.groupby(['Year'])['Return'].rank(ascending=False)
print(s)

収量

   Year Manager  Return  Rank
0  2012       A       3     2
1  2012       B       8     1
2  2011       A      20     2
3  2011       B      30     1

OPの改訂された質問に対処するには:エラーメッセージ

ValueError: cannot reindex from a duplicate axis

インデックスの値が重複しているDataFrameをgroupby/rankしようとすると発生します。追加後に一意のインデックス値を持つようにsを構築することにより、問題を回避できます。

s = pd.DataFrame([['2012', 'A', 3], ['2012', 'B', 8], ['2011', 'A', 20], ['2011', 'B', 30]], columns=['Year', 'Manager', 'Return'])
b = pd.DataFrame([['2012', 'A', 3], ['2012', 'B', 8], ['2011', 'A', 20], ['2011', 'B', 30]], columns=['Year', 'Manager', 'Return'])
s = s.append(b, ignore_index=True)

収量

   Year Manager  Return
0  2012       A       3
1  2012       B       8
2  2011       A      20
3  2011       B      30
4  2012       A       3
5  2012       B       8
6  2011       A      20
7  2011       B      30

を使用して新しい行をすでに追加している場合

s = s.append(b)

次に、reset_indexを使用して一意のインデックスを作成します。

s = s.reset_index(drop=True)
26
unutbu