pandas の nlargest と nsmallest で上位・下位を素早く取得する

データの中から上位や下位の値を取り出したいとき、sort_values してから head を使う方法が一般的です。しかし pandas の nlargest と nsmallest を使えば、ソートと抽出を 1 ステップで実行でき、大きなデータセットではパフォーマンスの面でも有利になります。

nlargest で上位 n 件を取得する

nlargest は指定した列の値が大きい順に上位 n 行を返します。

import pandas as pd

df = pd.DataFrame({
    "name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
    "score": [85, 92, 78, 96, 88],
    "age": [25, 30, 22, 28, 35]
})

top3 = df.nlargest(3, "score")
print(top3)

Diana(96)、Bob(92)、Eve(88)の順に 3 行が返されます。sort_values(“score”, ascending=False).head(3) と同じ結果ですが、nlargest のほうが簡潔に書けます。

nsmallest で下位 n 件を取得する

nsmallest は逆に、値が小さい順に下位 n 行を返します。

bottom2 = df.nsmallest(2, "score")
print(bottom2)

Charlie(78)と Alice(85)が取得されます。

nlargest(n, column)

指定列の値が大きい上位 n 行を返す

nsmallest(n, column)

指定列の値が小さい下位 n 行を返す

複数列で順位を決める

同じ値があった場合の順序を制御するために、列名をリストで渡せます。

df2 = pd.DataFrame({
    "name": ["A", "B", "C", "D"],
    "score": [90, 90, 85, 95],
    "age": [25, 30, 22, 28]
})

result = df2.nlargest(3, ["score", "age"])
print(result)

score が同点の場合、次に age で比較されます。1 つ目の列で決まらなかったときに 2 つ目の列がタイブレーカーになるわけです。

keep 引数で重複の扱いを変える

同順位の行が複数ある場合の扱いは keep 引数で制御します。

first最初に出現した行を優先する(デフォルト)
last最後に出現した行を優先する
all同順位の行をすべて含める(n を超える場合あり)
result = df2.nlargest(2, "score", keep="all")
print(result)

keep=“all” にすると、2 位タイが 2 人いれば 3 行が返される可能性があります。ランキングを作るときに「同率の場合は全員含める」というルールにしたい場合に使えます。

パフォーマンスの違い

nlargest と nsmallest は内部的に部分ソート(ヒープ)アルゴリズムを使用しており、全件をソートする sort_values よりも効率的です。データが数百万行以上ある場合、上位 10 件だけを取り出すのに全件ソートするのは無駄が大きくなります。nlargest なら必要な分だけを効率的に抽出するため、大規模データほど速度の差が顕著になるでしょう。

ランキングの作成やワースト分析など、上位・下位のデータだけが必要な場面では、sort_values + head の代わりに nlargest / nsmallest を使うことを検討してみてください。