pandasドリル第16回の問題は「全教科でTop3の順位を追加するには?」です。
つとむ先生の紹介
20数年、最適化関連の案件に従事するビープラウドの技術士(情報工学)。2014年より最適化のモデル作成にPythonを使い始め、効率的に開発できるようになる。東京海洋大学、青山学院大学、慶應義塾大学、上智大学に非常勤講師としての勤務経験がある。また、オペレーションズ・リサーチ学会に約30年所属し、理事を2期務めた。フェロー。
主な著書はモデリングの諸相、Python言語によるビジネスアナリティクス、今日から使える!組合せ最適化、データ分析ライブラリーを用いた最適化モデルの作り方
問題
下記のように、Point
のTop3の順位(Rank
)を追加してください。4位以下は、NaN
にしてください。
結果は、変数df
そのものを修正してください。
求められる結果
Name | Subject | Point | Rank | |
---|---|---|---|---|
0 | Alice | 国語 | 87 | 2.0 |
1 | Alice | 算数 | 72 | 3.0 |
2 | Bob | 国語 | 65 | NaN |
3 | Bob | 算数 | 92 | 1.0 |
問題で使うDataFrame
Name | Subject | Point | |
---|---|---|---|
0 | Alice | 国語 | 87 |
1 | Alice | 算数 | 72 |
2 | Bob | 国語 | 65 |
3 | Bob | 算数 | 92 |
import pandas as pd df = pd.DataFrame( [ ['Alice', '国語', 87], ['Alice', '算数', 72], ['Bob', '国語', 65], ['Bob', '算数', 92], ], columns=['Name', 'Subject', 'Point']) df
回答
df["Rank"] = df.Point.rank(ascending=False).sort_values()[:3]
解説
df.Point.rank(ascending=False)
でPoint
の順位になります。
df.Point.rank(ascending=False)
0 2.0 1 3.0 2 4.0 3 1.0 Name: Point, dtype: float64
さらに.sort_values()
をつなげて、順位でソートします。
df.Point.rank(ascending=False).sort_values()
3 1.0 0 2.0 1 3.0 2 4.0 Name: Point, dtype: float64
.iloc[:3]
を付けることで、3つだけにします。
df.Point.rank(ascending=False).sort_values().iloc[:3]
3 1.0 0 2.0 1 3.0 Name: Point, dtype: float64
df["Rank"]
に上記を代入します。
df["Rank"] = df.Point.rank(ascending=False).sort_values().iloc[:3]
右辺はSeriesです。Seriesを代入すると、右辺のインデックスに対応するdf
の部分にだけ代入されます。
右辺に対応するインデックスが存在しないdf["Rank"]
の値はNaNになります。
別解
df["Rank"] = float("nan") sr = df.Point.rank(ascending=False).sort_values()[:3] df.Rank.update(sr)
上記のようにdf.Rank.update()
を使うこともできます。
この場合、df["Rank"] = float("nan")
のように初期化が必要です。
お知らせ
PyQの「pandasチャレンジ」パートではこの問題を実際に手を動かしながら学べます。
PyQで学習中の方はぜひトライしてみてください。
https://pyq.jp/quests/pandas_challenge_2_2/
前回の問題
第15回つとむ先生のpandasドリル【教科ごとの順位を追加するには?】は、こちらからご覧ください。