Pandas sort_valuesの使い方:昇順・降順、複数列のソートも簡単マスター
Pandasは、Pythonでデータ分析を行う上で非常に強力なライブラリです。その中でもsort_values
関数は、DataFrameのデータを特定の列の値に基づいてソートするための基本的な、そして重要な機能です。この記事では、sort_values
関数の基本的な使い方から、昇順・降順の指定、複数列でのソート、欠損値の扱い、パフォーマンスの最適化まで、徹底的に解説します。具体的なコード例を交えながら、実践的なノウハウを身につけ、データ分析の効率を飛躍的に向上させましょう。
1. sort_values
関数の基本
sort_values
関数は、DataFrameオブジェクトに対して使用され、指定された列の値に基づいて行を並べ替えた新しいDataFrameを返します。元のDataFrameは変更されません。
構文:
python
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, na_position='last', ignore_index=False, key=None)
引数の説明:
by
: ソートに使用する列名(文字列)または列名のリスト。必須引数です。axis
: ソートする軸を指定します。axis=0
(行) がデフォルトです。列をソートする場合はaxis=1
を指定します (あまり一般的ではありません)。ascending
: ソート順序を指定します。True
(昇順) がデフォルトです。False
を指定すると降順になります。inplace
:True
を指定すると、元のDataFrameが直接変更されます。デフォルトはFalse
で、ソートされた新しいDataFrameが返されます。注意して使用してください。na_position
: 欠損値 (NaN) の位置を指定します。'last'
(最後に配置) がデフォルトです。'first'
を指定すると最初に配置されます。ignore_index
:True
を指定すると、ソート後のインデックスがリセットされ、連番になります。デフォルトはFalse
で、元のインデックスが保持されます。key
: ソート前に各値を変換する関数を指定します。例えば、文字列を大文字・小文字を区別せずにソートしたい場合に便利です。
基本的な使用例:
“`python
import pandas as pd
サンプルデータフレームの作成
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 40, 28, 35],
‘点数’: [80, 90, 75, 85, 95]}
df = pd.DataFrame(data)
print(“元のデータフレーム:\n”, df)
‘年齢’列で昇順にソート
df_sorted_age_asc = df.sort_values(by=’年齢’)
print(“\n’年齢’列で昇順ソート:\n”, df_sorted_age_asc)
‘点数’列で降順にソート
df_sorted_score_desc = df.sort_values(by=’点数’, ascending=False)
print(“\n’点数’列で降順ソート:\n”, df_sorted_score_desc)
“`
この例では、まずサンプルデータフレームを作成し、sort_values
関数を使って、年齢
列で昇順、点数
列で降順にそれぞれソートしています。ascending
引数をFalse
にすることで降順を指定できるのがポイントです。
2. 昇順・降順の指定
ascending
引数は、ソート順序を制御するために使用します。
ascending=True
: 昇順 (デフォルト)ascending=False
: 降順
例:
“`python
import pandas as pd
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 40, 28, 35],
‘点数’: [80, 90, 75, 85, 95]}
df = pd.DataFrame(data)
‘点数’列で昇順ソート
df_sorted_score_asc = df.sort_values(by=’点数’, ascending=True)
print(“\n’点数’列で昇順ソート:\n”, df_sorted_score_asc)
‘点数’列で降順ソート
df_sorted_score_desc = df.sort_values(by=’点数’, ascending=False)
print(“\n’点数’列で降順ソート:\n”, df_sorted_score_desc)
“`
この例では、ascending=True
とascending=False
をそれぞれ指定して、点数
列で昇順と降順のソートを比較しています。
3. 複数列でのソート
複数の列を基準にソートするには、by
引数に列名のリストを渡します。この場合、リストの順番がソートの優先順位になります。
例:
“`python
import pandas as pd
data = {‘学部’: [‘工学部’, ‘理学部’, ‘工学部’, ‘理学部’, ‘経済学部’],
‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 30, 28, 35],
‘点数’: [80, 90, 75, 85, 95]}
df = pd.DataFrame(data)
‘学部’列で昇順、次に’年齢’列で降順にソート
df_sorted_multi = df.sort_values(by=[‘学部’, ‘年齢’], ascending=[True, False])
print(“\n’学部’列で昇順、’年齢’列で降順ソート:\n”, df_sorted_multi)
“`
この例では、by=['学部', '年齢']
とascending=[True, False]
を指定しています。これにより、まず学部
列で昇順にソートされ、次に同じ学部
に属する行は年齢
列で降順にソートされます。 ascending
リストは、by
リストの各列に対応するソート順序を指定する必要があります。リストの長さが異なる場合はエラーが発生します。
4. 欠損値 (NaN) の扱い
DataFrameに欠損値 (NaN) が含まれている場合、na_position
引数を使用して、欠損値をソート結果のどこに配置するかを指定できます。
na_position='last'
(デフォルト): 欠損値を最後に配置na_position='first'
: 欠損値を最初に配置
例:
“`python
import pandas as pd
import numpy as np
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 40, np.nan, 35],
‘点数’: [80, np.nan, 75, 85, 95]}
df = pd.DataFrame(data)
print(“元のデータフレーム:\n”, df)
‘年齢’列で昇順ソート、欠損値を最後に配置 (デフォルト)
df_sorted_age_last = df.sort_values(by=’年齢’, na_position=’last’)
print(“\n’年齢’列で昇順ソート、欠損値を最後に配置:\n”, df_sorted_age_last)
‘年齢’列で昇順ソート、欠損値を最初に配置
df_sorted_age_first = df.sort_values(by=’年齢’, na_position=’first’)
print(“\n’年齢’列で昇順ソート、欠損値を最初に配置:\n”, df_sorted_age_first)
“`
この例では、年齢
列に欠損値が含まれています。na_position='last'
とna_position='first'
をそれぞれ指定して、欠損値の配置がどのように変化するかを確認できます。
5. inplace
引数による元のDataFrameの変更
inplace=True
を指定すると、ソートされた結果で元のDataFrameが直接変更されます。デフォルトはinplace=False
で、ソートされた新しいDataFrameが返されます。
注意: inplace=True
を使用すると、元のDataFrameが変更されるため、注意して使用する必要があります。特に、データの変更履歴を保持する必要がある場合は、inplace=False
を使用し、ソートされた新しいDataFrameを変数に格納することをお勧めします。
例:
“`python
import pandas as pd
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 40, 28, 35],
‘点数’: [80, 90, 75, 85, 95]}
df = pd.DataFrame(data)
print(“元のデータフレーム:\n”, df)
‘年齢’列で昇順ソート、元のDataFrameを直接変更
df.sort_values(by=’年齢’, inplace=True)
print(“\n’年齢’列で昇順ソート後 (inplace=True):\n”, df)
“`
この例では、inplace=True
を指定しているため、df.sort_values()
の実行後、df
自体がソートされた状態に変化しています。
6. ignore_index
引数によるインデックスのリセット
ignore_index=True
を指定すると、ソート後のDataFrameのインデックスがリセットされ、0から始まる連番になります。デフォルトはignore_index=False
で、元のインデックスが保持されます。
例:
“`python
import pandas as pd
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 40, 28, 35],
‘点数’: [80, 90, 75, 85, 95]}
df = pd.DataFrame(data, index=[‘A’, ‘B’, ‘C’, ‘D’, ‘E’])
print(“元のデータフレーム:\n”, df)
‘年齢’列で昇順ソート、インデックスをリセット
df_sorted_reset_index = df.sort_values(by=’年齢’, ignore_index=True)
print(“\n’年齢’列で昇順ソート後 (ignore_index=True):\n”, df_sorted_reset_index)
‘年齢’列で昇順ソート、元のインデックスを保持 (デフォルト)
df_sorted_keep_index = df.sort_values(by=’年齢’, ignore_index=False)
print(“\n’年齢’列で昇順ソート後 (ignore_index=False):\n”, df_sorted_keep_index)
“`
この例では、元のDataFrameに’A’, ‘B’, ‘C’, ‘D’, ‘E’というインデックスが設定されています。ignore_index=True
を指定すると、ソート後のインデックスが0から始まる連番にリセットされます。一方、ignore_index=False
(デフォルト) を指定すると、元のインデックスが保持されます。
7. key
引数によるソート前の値の変換
key
引数を使用すると、ソート前に各値を変換する関数を指定できます。これは、例えば、文字列を大文字・小文字を区別せずにソートしたい場合に便利です。
例:
“`python
import pandas as pd
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘名前_ローマ字’: [‘tanaka’, ‘Sato’, ‘Suzuki’, ‘takahashi’, ‘Ito’]}
df = pd.DataFrame(data)
print(“元のデータフレーム:\n”, df)
‘名前_ローマ字’列を大文字・小文字を区別せずに昇順ソート
df_sorted_key = df.sort_values(by=’名前_ローマ字’, key=lambda x: x.str.lower())
print(“\n’名前_ローマ字’列を大文字・小文字を区別せずに昇順ソート:\n”, df_sorted_key)
“`
この例では、key=lambda x: x.str.lower()
を指定しています。lambda
関数は、名前_ローマ字
列の各値を小文字に変換してからソートを行います。これにより、大文字・小文字を区別せずにアルファベット順にソートされます。
8. 実践的な応用例
例1: CSVファイルの読み込みとソート
“`python
import pandas as pd
CSVファイルを読み込む (例: ‘sales_data.csv’)
df = pd.read_csv(‘sales_data.csv’)
‘売上’列で降順にソート
df_sorted_sales = df.sort_values(by=’売上’, ascending=False)
ソート結果を新しいCSVファイルに保存 (例: ‘sorted_sales_data.csv’)
df_sorted_sales.to_csv(‘sorted_sales_data.csv’, index=False)
print(df_sorted_sales.head()) # 上位5件を表示
“`
この例では、CSVファイルを読み込み、売上
列で降順にソートし、ソート結果を新しいCSVファイルに保存しています。to_csv
関数のindex=False
引数は、インデックスをファイルに書き込まないように指定します。
例2: グループごとのソート
“`python
import pandas as pd
data = {‘グループ’: [‘A’, ‘A’, ‘B’, ‘B’, ‘C’, ‘C’],
‘値’: [10, 5, 15, 8, 20, 12]}
df = pd.DataFrame(data)
グループごとに値を昇順にソート
df_sorted_group = df.groupby(‘グループ’).apply(lambda x: x.sort_values(by=’値’))
print(df_sorted_group)
“`
この例では、groupby
関数を使用してグループごとにデータを分割し、apply
関数を使って各グループを値
列で昇順にソートしています。
例3: 複雑な条件でのソート
複数の条件を組み合わせて複雑なソートを行うことも可能です。例えば、特定の範囲の値を持つ行を優先的にソートしたり、文字列の長さに基づいてソートしたりできます。
“`python
import pandas as pd
data = {‘名前’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘高橋’, ‘伊藤’],
‘年齢’: [30, 25, 40, 28, 35],
‘点数’: [80, 90, 75, 85, 95],
‘備考’: [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]}
df = pd.DataFrame(data)
1. 点数が80点以上の行を優先的に上位にソート
2. その後、年齢で昇順ソート
def custom_sort(df):
# 点数が80点以上かどうかを示す列を作成
df[‘priority’] = df[‘点数’] >= 80
# 優先順位列と年齢でソート
df_sorted = df.sort_values(by=[‘priority’, ‘年齢’], ascending=[False, True])
# 優先順位列を削除
df_sorted = df_sorted.drop(‘priority’, axis=1)
return df_sorted
df_sorted_custom = custom_sort(df.copy()) #元のデータフレームをコピーして変更
print(df_sorted_custom)
``
custom_sort
この例では、まず点数が80点以上の行を上位にソートし、その後、年齢で昇順にソートしています。カスタムのソート関数を使用することで、複雑な条件に基づいたソートが可能になります。重要なのは、元のDataFrameを直接変更しないために、
df.copy()`でコピーを作成している点です。
9. sort_values
のパフォーマンス最適化
大規模なデータフレームをソートする場合、パフォーマンスが重要な考慮事項となります。以下に、sort_values
のパフォーマンスを最適化するためのヒントをいくつか紹介します。
- 適切なデータ型を使用する: ソートに使用する列のデータ型が適切であることを確認してください。例えば、数値データは数値型 (int, float) であるべきで、文字列型で表現されていないか確認します。
- インデックスを活用する: DataFrameに適切なインデックスを設定すると、ソートのパフォーマンスが向上する場合があります。特に、ソートに使用する列が既にインデックスとして設定されている場合は、パフォーマンスが大幅に向上する可能性があります。
- 不要なデータの削除: ソートに必要な列のみを含むようにデータフレームを絞り込むことで、ソートの対象となるデータ量を減らし、パフォーマンスを向上させることができます。
nlargest
とnsmallest
の利用: 特定の上位または下位のN件を取得したい場合は、sort_values
の代わりにnlargest
とnsmallest
を使用すると、より効率的に処理できる場合があります。これらの関数は、上位または下位のN件のみを抽出するため、全体のソートを行う必要がありません。
例:
“`python
import pandas as pd
import numpy as np
import time
大規模なデータフレームの作成
data = {‘col1’: np.random.rand(1000000),
‘col2’: np.random.randint(0, 100, 1000000)}
df = pd.DataFrame(data)
sort_valuesを使ったソート
start_time = time.time()
df_sorted = df.sort_values(by=’col1′)
end_time = time.time()
print(f”sort_valuesの実行時間: {end_time – start_time:.4f}秒”)
nlargestを使ったソート (上位10件)
start_time = time.time()
df_largest = df.nlargest(10, ‘col1’)
end_time = time.time()
print(f”nlargestの実行時間: {end_time – start_time:.4f}秒”)
“`
この例では、sort_values
とnlargest
の実行時間を比較しています。nlargest
は、上位N件のみを取得する場合に、sort_values
よりも高速に処理できることがわかります。
10. まとめ
sort_values
関数は、Pandas DataFrameのデータを効率的にソートするための非常に強力なツールです。この記事では、基本的な使い方から、昇順・降順の指定、複数列でのソート、欠損値の扱い、inplace
引数の使用、ignore_index
引数によるインデックスのリセット、key
引数によるソート前の値の変換、実践的な応用例、そしてパフォーマンスの最適化まで、sort_values
関数のあらゆる側面を網羅的に解説しました。
これらの知識を習得することで、データ分析のワークフローを効率化し、より高度なデータ操作を行うことができるようになります。ぜひ、この記事を参考に、sort_values
関数を使いこなして、データ分析スキルを向上させてください。Pandasのドキュメントも合わせて参照することで、さらに深い理解を得ることができます。