pandas.DataFrame, Seriesをソートするsort_values, sort_index
pandasでDataFrame
やSeries
をソート(並び替え)するには、sort_values()
およびsort_index()
メソッドを使う。昇順・降順を切り替えたり、複数列を基準にソートしたりできる。
なお、古いバージョンにあったsort()
メソッドは廃止されているので注意。
昇順・降順に並べ替えるのではなく、昇順・降順に順位付けした結果を得るにはrank()
、行名・列名を指定して任意の順番に並べ替えるにはreindex()
を使う。
n個の最大値・最小値(大きい方からn個、小さい方からn個)を含む行・要素を取り出すnlargest()
, nsmallest()
もある。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として以下のデータを使用する。
import pandas as pd
print(pd.__version__)
# 2.1.4
df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
例はDataFrame
だが、Series
でもsort_values()
とsort_index()
が用意されている。使い方は同じ。
要素でソートするsort_values()
要素の値に応じてソートするにはsort_values()
メソッドを使う。
- pandas.DataFrame.sort_values — pandas 2.1.4 documentation
- pandas.Series.sort_values — pandas 2.1.4 documentation
基準列を指定: 引数by
ソートしたい列のラベル(列名)を第一引数by
に指定する。
print(df.sort_values('age'))
# name age state point
# 2 Charlie 18 CA 70
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
print(df.sort_values('state'))
# name age state point
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
# 0 Alice 24 NY 64
# 5 Frank 30 NY 57
# 3 Dave 68 TX 70
複数列を基準にソート
第一引数by
をリストで指定すると、複数列を基準にソートできる。
リストの後ろに指定した列から順番にソートされ、最終的にはリストの先頭に指定した列でソートされる。
print(df.sort_values(['age', 'state']))
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
# 0 Alice 24 NY 64
# 5 Frank 30 NY 57
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
print(df.sort_values(['state', 'age']))
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
# 1 Bob 42 CA 92
# 0 Alice 24 NY 64
# 5 Frank 30 NY 57
# 3 Dave 68 TX 70
昇順・降順の指定: 引数ascending
デフォルトは昇順。降順にするには引数ascending
をFalse
にする。
print(df.sort_values('age', ascending=False))
# name age state point
# 3 Dave 68 TX 70
# 1 Bob 42 CA 92
# 5 Frank 30 NY 57
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 2 Charlie 18 CA 70
複数列を基準にソートする場合、引数ascending
をリストで指定すると、それぞれの列に対して昇順・降順を選択できる。
print(df.sort_values(['age', 'state'], ascending=False))
# name age state point
# 3 Dave 68 TX 70
# 1 Bob 42 CA 92
# 5 Frank 30 NY 57
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 2 Charlie 18 CA 70
print(df.sort_values(['age', 'state'], ascending=[True, False]))
# name age state point
# 2 Charlie 18 CA 70
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
インデックスを振り直し: 引数ignore_index
デフォルトではインデックス(行名)も合わせて並べ替えられる。引数ignore_index
をTrue
とすると、0始まりの連番に振り直される。
print(df.sort_values('age', ignore_index=True))
# name age state point
# 0 Charlie 18 CA 70
# 1 Alice 24 NY 64
# 2 Ellen 24 CA 88
# 3 Frank 30 NY 57
# 4 Bob 42 CA 92
# 5 Dave 68 TX 70
欠損値NaNの扱い: 引数na_position
欠損値NaN
がある場合、デフォルトでは末尾に並べられる。
df_nan = df.copy()
df_nan.iloc[0, 1] = float('nan')
df_nan.iloc[4, 1] = float('nan')
print(df_nan)
# name age state point
# 0 Alice NaN NY 64
# 1 Bob 42.0 CA 92
# 2 Charlie 18.0 CA 70
# 3 Dave 68.0 TX 70
# 4 Ellen NaN CA 88
# 5 Frank 30.0 NY 57
print(df_nan.sort_values('age'))
# name age state point
# 2 Charlie 18.0 CA 70
# 5 Frank 30.0 NY 57
# 1 Bob 42.0 CA 92
# 3 Dave 68.0 TX 70
# 0 Alice NaN NY 64
# 4 Ellen NaN CA 88
引数na_position
を'first'
とすると先頭に並べられる。
print(df_nan.sort_values('age', na_position='first'))
# name age state point
# 0 Alice NaN NY 64
# 4 Ellen NaN CA 88
# 2 Charlie 18.0 CA 70
# 5 Frank 30.0 NY 57
# 1 Bob 42.0 CA 92
# 3 Dave 68.0 TX 70
欠損値を削除したり別の値に置換したりする方法については以下の記事を参照。
関数を適用した結果を元にソート: 引数key
Pythonの組み込み関数sorted()
などのように、sort_values()
でも引数key
を指定できる。引数key
に指定した関数がソートされる前に適用され、その結果を元にソートされる。
文字列の長さ(文字数)でソートする例は以下の通り。ラムダ式でSeries
の文字列メソッドを適用している。
print(df.sort_values('name', key=lambda s: s.str.len()))
# name age state point
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# 2 Charlie 18 CA 70
sort_values()
の引数key
には、Series
を受け取りSeries
やリストなどのarray-likeオブジェクトを返す関数を指定する必要があるので注意。
各要素に任意の関数を適用するにはmap()
メソッドを使う。以下の例では説明のためにSeries
の文字列メソッドを使わず、map()
で組み込み関数len()
を適用している。
# print(df.sort_values('name', key=len))
# TypeError: object of type 'int' has no len()
print(df.sort_values('name', key=lambda s: s.map(len)))
# name age state point
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# 2 Charlie 18 CA 70
引数key
を利用すると任意のルールに従って並べ替えられる。都道府県名を都道府県コード順にソートする例は以下の記事を参照。
ソートアルゴリズムを指定: 引数kind
引数kind
にソートアルゴリズムを指定できる。'quicksort'
(デフォルト), 'mergesort'
, 'heapsort'
, 'stable'
を指定可能。各アルゴリズムの詳細は以下のNumPy公式ドキュメントを参照。
複数列を基準にソートする場合はこの引数の指定は無視される。
行を基準に列をソート: 引数axis
これまでの例のように、デフォルトでは列を基準に行がソートされる。行を基準に列をソートするには引数axis
を1
または'columns'
とする。
数値と文字列が混在しているとエラーになるので、ここではselect_dtypes()
で数値の列のみを抽出している。
df_num = df.select_dtypes('number')
print(df_num)
# age point
# 0 24 64
# 1 42 92
# 2 18 70
# 3 68 70
# 4 24 88
# 5 30 57
print(df_num.sort_values(1, axis=1, ascending=False))
# point age
# 0 64 24
# 1 92 42
# 2 70 18
# 3 70 68
# 4 88 24
# 5 57 30
元のオブジェクトを変更: 引数inplace
デフォルトではソートされた新たなオブジェクトが返されるが、引数inplace
をTrue
とすると、元のオブジェクト自体が変更される。
df_copy = df.copy()
df_copy.sort_values('age', inplace=True)
print(df_copy)
# name age state point
# 2 Charlie 18 CA 70
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
インデックス(行名・列名)でソートするsort_index()
インデックス(行名・列名)でソートするにはsort_index()
メソッドを使う。
- pandas.DataFrame.sort_index — pandas 2.1.4 documentation
- pandas.Series.sort_index — pandas 2.1.4 documentation
行名indexでソート
デフォルトでは行名index
に従って行がソートされる。
df_sorted = df.sort_values('age')
print(df_sorted)
# name age state point
# 2 Charlie 18 CA 70
# 0 Alice 24 NY 64
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
print(df_sorted.sort_index())
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
列名columnsでソート: 引数axis
引数axis
を1
または'columns'
とすると、列名columns
に従って列がソートされる。
print(df.sort_index(axis=1))
# age name point state
# 0 24 Alice 64 NY
# 1 42 Bob 92 CA
# 2 18 Charlie 70 CA
# 3 68 Dave 70 TX
# 4 24 Ellen 88 CA
# 5 30 Frank 57 NY
sort_values()と同じ引数を指定可能
sort_index()
でも引数ascending
, ignore_index
, na_position
, key
, kind
, inplace
を指定可能。行名index
や列名columns
が対象になるだけで、使い方はsort_values()
と同じ。
print(df.sort_index(axis=1, ascending=False, key=lambda s: s.str.len()))
# state point name age
# 0 NY 64 Alice 24
# 1 CA 92 Bob 42
# 2 CA 70 Charlie 18
# 3 TX 70 Dave 68
# 4 CA 88 Ellen 24
# 5 NY 57 Frank 30