Skip to content

Pandas Sort Values:PythonでのDataFrameソート完全ガイド

Updated on

ソートされていないデータは分析が困難です。何千行ものデータをスクロールして最高売上、最新の日付、最低エラー率を探しても、データが整理されていれば明らかなパターンを見逃してしまいます。Pythonのリストソートは単純なケースでは機能しますが、DataFrameは複数の列、混合型、欠損値を持っており、リストでは処理できません。

Pandasのsort_values()は、昇順/降順の制御、null値の配置、安定性を完全に制御しながら、1つ以上の列でDataFrameをソートします。このガイドでは、実際のデータ作業で遭遇するすべてのソートパターンをカバーします。

📚

sort_values()を使った基本的なソート

単一列でソート

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'score': [85, 92, 78, 95, 88],
    'age': [25, 30, 22, 28, 35]
})
 
# scoreでソート(デフォルトは昇順)
sorted_df = df.sort_values('score')
print(sorted_df)
#       name  score  age
# 2  Charlie     78   22
# 0    Alice     85   25
# 4      Eve     88   35
# 1      Bob     92   30
# 3    Diana     95   28

降順ソート

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'score': [85, 92, 78, 95, 88],
    'age': [25, 30, 22, 28, 35]
})
 
# 最高スコアを先頭に
sorted_df = df.sort_values('score', ascending=False)
print(sorted_df)
#       name  score  age
# 3    Diana     95   28
# 1      Bob     92   30
# 4      Eve     88   35
# 0    Alice     85   25
# 2  Charlie     78   22

インプレースソート

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [85, 92, 78]
})
 
# dfを直接変更(コピーは作成されない)
df.sort_values('score', inplace=True)
print(df)
#       name  score
# 2  Charlie     78
# 0    Alice     85
# 1      Bob     92

複数列ソート

複数列でソート

import pandas as pd
 
df = pd.DataFrame({
    'department': ['Sales', 'Engineering', 'Sales', 'Engineering', 'Sales'],
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'salary': [70000, 85000, 65000, 90000, 70000]
})
 
# まず部門でソートし、次に各部門内で給与でソート
sorted_df = df.sort_values(['department', 'salary'])
print(sorted_df)
#     department     name  salary
# 1  Engineering      Bob   85000
# 3  Engineering    Diana   90000
# 2        Sales  Charlie   65000
# 0        Sales    Alice   70000
# 4        Sales      Eve   70000

昇順/降順の混合

import pandas as pd
 
df = pd.DataFrame({
    'department': ['Sales', 'Engineering', 'Sales', 'Engineering', 'Sales'],
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'salary': [70000, 85000, 65000, 90000, 70000]
})
 
# 部門は昇順、給与は降順
sorted_df = df.sort_values(
    ['department', 'salary'],
    ascending=[True, False]
)
print(sorted_df)
#     department     name  salary
# 3  Engineering    Diana   90000
# 1  Engineering      Bob   85000
# 0        Sales    Alice   70000
# 4        Sales      Eve   70000
# 2        Sales  Charlie   65000

欠損値(NaN)の処理

デフォルトでは、ソート方向に関係なくNaN値は末尾に配置されます。na_positionで制御できます:

import pandas as pd
import numpy as np
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
    'score': [85, np.nan, 78, np.nan]
})
 
# NaNを末尾に(デフォルト)
print(df.sort_values('score'))
#       name  score
# 2  Charlie   78.0
# 0    Alice   85.0
# 1      Bob    NaN
# 3    Diana    NaN
 
# NaNを先頭に
print(df.sort_values('score', na_position='first'))
#       name  score
# 1      Bob    NaN
# 3    Diana    NaN
# 2  Charlie   78.0
# 0    Alice   85.0

sort_index()でインデックスによるソート

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [85, 92, 78]
}, index=[2, 0, 1])
 
# インデックスでソート
print(df.sort_index())
#      name  score
# 0     Bob     92
# 1  Charlie    78
# 2   Alice     85
 
# 列名でソート(axis=1)
df2 = pd.DataFrame({
    'c': [1, 2], 'a': [3, 4], 'b': [5, 6]
})
print(df2.sort_index(axis=1))
#    a  b  c
# 0  3  5  1
# 1  4  6  2

ソート後のインデックスリセット

ソート後、元のインデックスは保持されます。きれいな連番インデックスを取得するには:

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [85, 92, 78]
})
 
sorted_df = df.sort_values('score').reset_index(drop=True)
print(sorted_df)
#       name  score
# 0  Charlie     78
# 1    Alice     85
# 2      Bob     92

drop=Trueを使用して古いインデックスを破棄します。使用しない場合、古いインデックスが列になります。

カスタムソート順

カテゴリ型を使用

import pandas as pd
 
df = pd.DataFrame({
    'priority': ['Medium', 'High', 'Low', 'High', 'Medium'],
    'task': ['Task A', 'Task B', 'Task C', 'Task D', 'Task E']
})
 
# カスタム順序を定義
priority_order = pd.CategoricalDtype(['Low', 'Medium', 'High'], ordered=True)
df['priority'] = df['priority'].astype(priority_order)
 
sorted_df = df.sort_values('priority')
print(sorted_df)
#   priority    task
# 2      Low  Task C
# 0   Medium  Task A
# 4   Medium  Task E
# 1     High  Task B
# 3     High  Task D

keyパラメータを使用

import pandas as pd
 
df = pd.DataFrame({
    'name': ['alice', 'Bob', 'CHARLIE', 'diana'],
    'score': [85, 92, 78, 95]
})
 
# 大文字小文字を区別しないソート
sorted_df = df.sort_values('name', key=lambda x: x.str.lower())
print(sorted_df)
#       name  score
# 0    alice     85
# 1      Bob     92
# 2  CHARLIE     78
# 3    diana     95

メソッド比較

メソッド用途元のデータを変更?戻り値
sort_values(col)列の値でソートいいえ(inplace=Trueの場合を除く)ソート済みDataFrame
sort_values([col1, col2])複数列でソートいいえ(inplace=Trueの場合を除く)ソート済みDataFrame
sort_index()行インデックスでソートいいえ(inplace=Trueの場合を除く)ソート済みDataFrame
nsmallest(n, col)最小のn値を取得いいえDataFrameサブセット
nlargest(n, col)最大のn値を取得いいえDataFrameサブセット
rank()値にランクを割り当ていいえランクのSeries

パフォーマンスのヒント

Top-NにはnLargest()とnsmallest()を使用

上位N行または下位N行のみが必要な場合、nlargest()nsmallest()はDataFrame全体をソートするよりも高速です:

import pandas as pd
import numpy as np
 
# 大規模DataFrame
df = pd.DataFrame({
    'id': range(1_000_000),
    'value': np.random.randn(1_000_000)
})
 
# 高速:上位10件のみを検索
top_10 = df.nlargest(10, 'value')
 
# 低速:すべてをソートしてからスライス
top_10_slow = df.sort_values('value', ascending=False).head(10)

安定ソートと不安定ソート

import pandas as pd
 
df = pd.DataFrame({
    'group': ['A', 'B', 'A', 'B'],
    'value': [1, 1, 2, 2],
    'order': [1, 2, 3, 4]
})
 
# 安定ソート(デフォルト)は同値の元の順序を保持
stable = df.sort_values('value', kind='mergesort')  # デフォルト
 
# 不安定ソート(大規模データセットでは高速)
unstable = df.sort_values('value', kind='quicksort')

実践的な例

日付のソート

import pandas as pd
 
df = pd.DataFrame({
    'event': ['Launch', 'Meeting', 'Deadline', 'Review'],
    'date': pd.to_datetime(['2026-03-15', '2026-01-10', '2026-02-28', '2026-01-05'])
})
 
# 時系列順
print(df.sort_values('date'))
#      event       date
# 3   Review 2026-01-05
# 1  Meeting 2026-01-10
# 2 Deadline 2026-02-28
# 0   Launch 2026-03-15

GroupByと組み合わせたソート

import pandas as pd
 
df = pd.DataFrame({
    'store': ['A', 'A', 'B', 'B', 'A', 'B'],
    'product': ['X', 'Y', 'X', 'Y', 'Z', 'Z'],
    'revenue': [100, 250, 150, 300, 200, 175]
})
 
# 各店舗で収益が最も高い商品
top_per_store = (df.sort_values('revenue', ascending=False)
                   .groupby('store')
                   .head(1))
print(top_per_store)
#   store product  revenue
# 3     B       Y      300
# 1     A       Y      250

ソートデータの視覚的探索

DataFrameをソートしてパターンを見つけた後、PyGWalker (opens in a new tab)を使えばJupyterでインタラクティブなドラッグ&ドロップチャートを通じて同じデータを探索できます——追加のコードは不要です:

import pygwalker as pyg
 
walker = pyg.walk(sorted_df)

よくある質問

pandasでDataFrameを列でソートするには?

df.sort_values('column_name')で昇順、df.sort_values('column_name', ascending=False)で降順にソートします。複数列の場合はリストを渡します:df.sort_values(['col1', 'col2'])

複数列を異なる順序でソートするには?

ascendingにブール値のリストを渡します:df.sort_values(['col1', 'col2'], ascending=[True, False])。これによりcol1は昇順、col2は降順でソートされます。

ソート時にNaN値はどこに配置される?

デフォルトでは、ソート方向に関係なくNaN値は末尾に配置されます。na_position='first'を使用して先頭に配置できます:df.sort_values('col', na_position='first')

sort_valuesとsort_indexの違いは?

sort_values()は列の値でソートします。sort_index()は行インデックス(またはaxis=1で列インデックス)でソートします。データのソートにはsort_valuesを、インデックスラベルによる順序付けにはsort_indexを使用します。

コピーを作成せずにDataFrameをインプレースでソートするには?

inplace=Trueを渡します:df.sort_values('col', inplace=True)。これは元のDataFrameを変更しNoneを返します。ただし、モダンなpandasスタイルでは再代入が推奨されます:df = df.sort_values('col')

まとめ

sort_values()はpandasでDataFrameをソートするための主要なツールです。単純なソートには単一列名を、複数列ソートにはリストを、方向の制御にはascendingパラメータを使用します。na_positionで欠損値を処理し、Top-Nクエリにはnlargest()/nsmallest()を、カスタム順序にはCategoricalDtypeを使用します。ソートはデフォルトで新しいDataFrameを返すことを忘れないでください——きれいな連番インデックスが必要な場合はreset_index(drop=True)を使用してください。

📚