Python | データ処理:ソート sort_values

Python
スポンサーリンク

概要(sort_valuesは「列の値で並べ替えて“見やすく・計算しやすく”する基本操作)

pandasのsort_valuesは、指定した列の値を基準にDataFrameを並べ替えるメソッドです。昇順・降順、複数列の優先順位、欠損値の並び位置、独自キー関数などを柔軟に指定できます。初心者は「by(どの列で)」「ascending(昇順/降順)」「na_position(欠損の位置)」「key(前処理してから比較)」をまず押さえると、ほぼ全ての並び替えを安全にこなせます。


基本の使い方(単一列・降順・複数列の優先順位)

単一列で並べ替え(昇順がデフォルト)

import pandas as pd

df = pd.DataFrame({"name": ["Taro", "Hanako", "Jiro"], "score": [85, 92, 70]})
out = df.sort_values(by="score")
print(out)
#    name  score
# 2   Jiro     70
# 0   Taro     85
# 1  Hanako    92
Python

byに列名を渡すだけでOK。デフォルトは昇順です。

降順に並べる(ランキングで定番)

top = df.sort_values(by="score", ascending=False)
Python

ascending=Falseで降順。上位ランキングや最新日時の優先表示に使います。

複数列で並べる(優先順位を左から)

df = pd.DataFrame({
    "team": ["A","A","B","B"],
    "score": [80, 80, 90, 75],
    "name": ["Taro","Jiro","Hanako","Ken"]
})

# 1) team → 2) score降順 → 3) name昇順
out = df.sort_values(by=["team", "score", "name"], ascending=[True, False, True])
print(out)
Python

複数列は「左の条件が優先」。同点の並びを次の列で安定させるのがコツです。


欠損・文字列・日付の並べ替え(na_position・dtype・to_datetime)

欠損の位置を制御(na_position)

df = pd.DataFrame({"x": [3, None, 1, None]})
out_top = df.sort_values(by="x", na_position="first")   # NaNを先頭へ
out_bottom = df.sort_values(by="x", na_position="last") # デフォルト(末尾)
Python

欠損(NaN)を先頭/末尾のどちらに寄せるかで、見通しが変わります。

文字列は前処理してから並べる(大小・空白)

df = pd.DataFrame({"name": ["  Taro", "hanako", "Jiro "]})
out = df.sort_values(by="name", key=lambda s: s.str.strip().str.lower())
Python

keyで一時的な整形(strip/lower)をしてから比較すると、自然な順序になります。

日付はまず型変換(to_datetime)

df = pd.DataFrame({"date": ["2025-01-02", "2024-12-31", "2025-01-01"]})
df["date"] = pd.to_datetime(df["date"])    # 文字列→日時型へ
out = df.sort_values(by="date")            # 正しく時系列昇順に
Python

文字列のままだと辞書順になりがち。日時型へ変換してから並べます。


応用(自然順・カスタム順・インデックス・安定ソート)

自然順(末尾数字で比較したい)

products = pd.DataFrame({"code": ["A-2", "A-10", "A-1"]})
out = products.sort_values(
    by="code",
    key=lambda s: s.str.extract(r"(\d+)", expand=False).astype(int)
)
# A-1, A-2, A-10 の順に並ぶ
Python

数字部分を抽出して比較すれば、自然な数値順になります。

カスタム順(カテゴリの並びを固定する)

import pandas as pd
order = pd.CategoricalDtype(categories=["Low", "Medium", "High"], ordered=True)
df = pd.DataFrame({"level": ["High","Low","Medium","Low"]})
df["level"] = df["level"].astype(order)
out = df.sort_values(by="level")  # Low→Medium→High の順
Python

カテゴリ型で順序を定義すると、意図した並びをいつでも再現できます。

インデックスで並べる(sort_index)

df = pd.DataFrame({"x": [3,1,2]}, index=["b","c","a"])
out = df.sort_index()           # 行ラベルで並べ替え
out_desc = df.sort_index(ascending=False)
Python

行・列ラベルの順序制御はsort_indexで。行順が意味を持つレポートなどに役立ちます。

安定ソートと同点の扱い

sort_valuesは安定ソート(同値の相対順を保持)です。さらに列を加えて安定させたい場合は複数列で条件を与えます。


実践例(ランキング・最新状態抽出・グループ内順位)

ランキング(降順→順位列を追加)

df = pd.DataFrame({"name": ["A","B","C"], "score": [85, 92, 70]})
ranked = df.sort_values(by="score", ascending=False).reset_index(drop=True)
ranked["rank"] = ranked.index + 1
print(ranked)
#   name  score  rank
# 0    B     92     1
# 1    A     85     2
# 2    C     70     3
Python

降順→連番で素早くランキングが作れます。

最新状態だけを残す(時系列→keep=”last”)

hist = pd.DataFrame({
    "user_id": ["001","001","001","002","002"],
    "status": ["new","active","suspended","new","active"],
    "ts": ["2025-01-01","2025-02-01","2025-03-01","2025-01-10","2025-02-10"]
})
hist["ts"] = pd.to_datetime(hist["ts"])

latest = (
    hist.sort_values(by=["user_id","ts"])    # ユーザー別に時系列昇順
        .drop_duplicates(subset=["user_id"], keep="last")
)
print(latest)
Python

「並べ替え→重複排除」の型で、各ユーザーの最新行だけを残せます。

グループ内順位(store別の売上順位)

df = pd.DataFrame({
    "store": ["A","A","A","B","B"],
    "sales": [300, 280, 310, 200, 220]
})

df = df.sort_values(by=["store","sales"], ascending=[True, False])
df["rank_in_store"] = df.groupby("store").cumcount() + 1
print(df)
# storeごとの降順順位が付く
Python

並べてからgroupby.cumcountで「並び順に応じた連番」を付与できます。


つまずき対策(型の不一致・欠損と順序・複数列の昇降混在・inplace)

型の不一致で意図しない並びになる

数値と文字列が混じると比較できずエラーか、object扱いで辞書順になります。前処理でastype・to_datetime・str.lowerなど“型と整形”を必ず揃えます。

欠損(NaN)の並びは明示する

デフォルトでNaNは末尾です。最初に見たいならna_position=”first”、あるいはfillnaで仮値(例:極端な小/大)を入れて並べ替え→元に戻す流れをとります。

複数列の昇降を間違えない

ascendingは単一boolではなく、列数に合わせたリストで渡せます。「scoreだけ降順」のような混在はascending=[True, False, True]のように明示します。

inplaceは控えめに

# 推奨:代入で受ける
df = df.sort_values(by="score", ascending=False)
Python

inplace=Trueは副作用が読みにくく、デバッグ・テストで混乱しがち。結果を代入で受け取るのが安全です。


まとめ(by・ascending・na_position・keyを使い分け、前処理で“比較可能な状態”に)

sort_valuesは、列の値で並べ替えるための基礎メソッドです。単一列・降順・複数列の優先順位を使い分け、欠損の位置はna_positionで制御。文字列や日付はkeyや型変換で前処理してから比較し、カテゴリ順を定義すれば“意図した並び”を再現できます。並べる前に型と整形を揃える—このひと手間だけで、初心者でも迷いなく正確なソートを実現できます。

タイトルとURLをコピーしました