Pandas sort_valuesの使い方:昇順・降順、複数列のソートも簡単マスター

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=Trueascending=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)

``
この例では、まず点数が80点以上の行を上位にソートし、その後、年齢で昇順にソートしています。カスタムのソート関数
custom_sortを使用することで、複雑な条件に基づいたソートが可能になります。重要なのは、元のDataFrameを直接変更しないために、df.copy()`でコピーを作成している点です。

9. sort_valuesのパフォーマンス最適化

大規模なデータフレームをソートする場合、パフォーマンスが重要な考慮事項となります。以下に、sort_valuesのパフォーマンスを最適化するためのヒントをいくつか紹介します。

  • 適切なデータ型を使用する: ソートに使用する列のデータ型が適切であることを確認してください。例えば、数値データは数値型 (int, float) であるべきで、文字列型で表現されていないか確認します。
  • インデックスを活用する: DataFrameに適切なインデックスを設定すると、ソートのパフォーマンスが向上する場合があります。特に、ソートに使用する列が既にインデックスとして設定されている場合は、パフォーマンスが大幅に向上する可能性があります。
  • 不要なデータの削除: ソートに必要な列のみを含むようにデータフレームを絞り込むことで、ソートの対象となるデータ量を減らし、パフォーマンスを向上させることができます。
  • nlargestnsmallestの利用: 特定の上位または下位のN件を取得したい場合は、sort_valuesの代わりにnlargestnsmallestを使用すると、より効率的に処理できる場合があります。これらの関数は、上位または下位の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_valuesnlargestの実行時間を比較しています。nlargestは、上位N件のみを取得する場合に、sort_valuesよりも高速に処理できることがわかります。

10. まとめ

sort_values関数は、Pandas DataFrameのデータを効率的にソートするための非常に強力なツールです。この記事では、基本的な使い方から、昇順・降順の指定、複数列でのソート、欠損値の扱い、inplace引数の使用、ignore_index引数によるインデックスのリセット、key引数によるソート前の値の変換、実践的な応用例、そしてパフォーマンスの最適化まで、sort_values関数のあらゆる側面を網羅的に解説しました。

これらの知識を習得することで、データ分析のワークフローを効率化し、より高度なデータ操作を行うことができるようになります。ぜひ、この記事を参考に、sort_values関数を使いこなして、データ分析スキルを向上させてください。Pandasのドキュメントも合わせて参照することで、さらに深い理解を得ることができます。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール