Pandasにはデータの中身をソートする機能が備わっています。SeriesにもDataFrameでも同じ関数名が使えるのでデータ型の違いを気にせず使える利点があります。
本記事では
- Seriesでのsort_values関数の使い方
- DataFrameでのsort_values関数の使い方
について解説していきます。
インデックスの入れ替えにはsort_index関数を使います。この関数については以下の記事で解説しています。
Pandasでインデックスや列ラベルをソートするsort_index関数の使い方 /features/pandas-sort-index.html
sort_values関数
APIドキュメント
まずはSeriesとDataFrameで使うsort_values関数のAPIドキュメントを見ていきましょう。DataFrameで使うものはSeriesで使えるものよりも引数が少し増えただけなので一緒に見ていきます。
Series.sort_values(axis=0,ascending=True,inplace=False,kind=’quicksort’,na_position=’last’) DataFrame.sort_values(by,axis=0,ascending=True,inplace=False,kind=’quicksort’,na_position=’last’)
params:
パラメータ名 | 型 | 概要 |
---|---|---|
by(DataFrameのみ) | strかstrのリスト | どの列データ(もしくは行データ)を元にデータをソートするかを指定します。| |
axis | 0または’index’ 1または’columns’(DataFrameのみ) |
(省略可能)初期値0 行方向(0または’index’)にソートするのか、列方向(1または’columns’)にソートするのかを指定します。列方向に指定できるのはDataFrameだけです。 |
ascending | bool値 | (省略可能)初期値True Trueのときデータは昇順に並べ替えられます。Falseのときデータは降順に並べ替えられます。 |
inplace | bool値 | (省略可能)初期値False Trueのとき、ソートした結果を元の配列のデータと置き換えます。 |
kind | ‘quicksort’,’mergesort’ もしくは’heapsort’ |
(省略可能)初期値’quicksort’ ソートするときに使うアルゴリズムを選択します。 |
na_position | ‘first’または’last’ | (省略可能)初期値’last’ NaN値を先頭(‘first’)に置くか、最後尾(‘last’)に置くかを指定します。 |
returns:
値がソートされたSeriesまたはDataFrameが返されます
引数kind
でソートするアルゴリズムを変更できますが、ソートのアルゴリズムによる違いは以下の記事で扱っていますのでこちらを参照してください。
Seriesをソートする
まずはSeriesのデータからソートしていきます。特に引数を指定しない状態からやっていきます。
In [1]: import pandas as pd # pandasモジュールのインポート
In [3]: import numpy as np # NumPyのモジュールのインポートしておく
In [4]: series = pd.Series([7,3,1,np.nan,0,-12,5])
In [5]: series.sort_values() # 特に何も指定しないと昇順でソートされる
Out[5]:
5 -12.0
4 0.0
2 1.0
1 3.0
6 5.0
0 7.0
3 NaN
dtype: float64
先ほどは昇順で並べ替えられていましたが、降順に変更してみます。ascending=False
で変更可能です。
In [6]: series.sort_values(ascending=False) # 次は降順
Out[6]:
0 7.0
6 5.0
1 3.0
2 1.0
4 0.0
5 -12.0
3 NaN
dtype: float64
NaN値を先頭に持っていきたい時はna_position='first'
にすれば持って来れます。
In [7]: series.sort_values(na_position='first') # NaN値が先頭にくる
Out[7]:
3 NaN
5 -12.0
4 0.0
2 1.0
1 3.0
6 5.0
0 7.0
dtype: float64
In [8]: series.sort_values(na_position='last') # NaN値が最後尾にくる
Out[8]:
5 -12.0
4 0.0
2 1.0
1 3.0
6 5.0
0 7.0
3 NaN
dtype: float64
ソートされた結果を元のデータに反映させたいというときはinplace=True
を指定してください。
In [9]: series.sort_values(inplace=True) # ソートされた結果が元のSeriesに反映される
In [10]: series # 中身を確認する
Out[10]:
5 -12.0
4 0.0
2 1.0
1 3.0
6 5.0
0 7.0
3 NaN
dtype: float64
文字列データもソートすることが可能です。
In [11]: str_series = pd.Series(["a","A","c","E","f"])
In [12]: str_series.sort_values()
Out[12]:
1 A
3 E
0 a
2 c
4 f
dtype: object
昇順のときは大文字のA~Z、小文字のa~zと並び替えられます。ascending=False
にすればこれが逆になります。
In [13]: str_series.sort_values(ascending=False)
Out[13]:
4 f
2 c
0 a
3 E
1 A
dtype: object
DataFrameをソートする
次にDataFrameで使っていきます。DataFrameでsort_values
関数を使う時は必ずby
引数を指定して、どのデータを使ってソートするかを指定する必要があります。
行方向(デフォルト)でソートする場合を考えます。by="列ラベル"
で指定可能です。
In [14]: data = {"a": [3,1,-5,3,8,1,np.nan,0,-1],
...: "b": ["a","b","A","G","k","C","c","cc","d"]}
...:
In [15]: df = pd.DataFrame(data)
In [16]: df
Out[16]:
a b
0 3.0 a
1 1.0 b
2 -5.0 A
3 3.0 G
4 8.0 k
5 1.0 C
6 NaN c
7 0.0 cc
8 -1.0 d
In [17]: df.sort_values(by="a") # a列の列データを使ってソートする
Out[17]:
a b
2 -5.0 A
8 -1.0 d
7 0.0 cc
1 1.0 b
5 1.0 C
0 3.0 a
3 3.0 G
4 8.0 k
6 NaN c
In [18]: df.sort_values(by="b") # b列の列データを使ってソートする
Out[18]:
a b
2 -5.0 A
5 1.0 C
3 3.0 G
0 3.0 a
1 1.0 b
6 NaN c
7 0.0 cc
8 -1.0 d
4 8.0 k
複数の列を指定することも可能です。by=[ラベル名のリスト]
で指定できます。先頭にきたものから優先的にソートされていきます。
In [20]: df.sort_values(by=["a","b"])
Out[20]:
a b
2 -5.0 A
8 -1.0 d
7 0.0 cc
5 1.0 C
1 1.0 b
3 3.0 G
0 3.0 a
4 8.0 k
6 NaN c
In [21]: df.sort_values(by=["b","a"])
Out[21]:
a b
2 -5.0 A
5 1.0 C
3 3.0 G
0 3.0 a
1 1.0 b
6 NaN c
7 0.0 cc
8 -1.0 d
4 8.0 k
次にaxis
を指定してソートする方向を変更しましょう。列方向(axis=1 or 'columns'
)にソートするときはby="index名"
となることに注意します。新たに1つDataFrameを作成して試します。
In [25]: df2 = pd.DataFrame([
...: [1, 3, -1, 9],
...: ["a","B","bb","b"]
...: ], index=["sample1","sample2"])
In [26]: df2
Out[26]:
0 1 2 3
sample1 1 3 -1 9
sample2 a B bb b
In [27]: df2.sort_values(by="sample1",axis="columns") # axis=1でもよい
Out[27]:
2 0 1 3
sample1 -1 1 3 9
sample2 bb a B b
In [28]: df2.sort_values(by="sample2",axis=1)
Out[28]:
1 0 3 2
sample1 3 1 9 -1
sample2 B a b bb
残りの引数についてはSeriesのときと同様です。
In [29]: df
Out[29]:
a b
0 3.0 a
1 1.0 b
2 -5.0 A
3 3.0 G
4 8.0 k
5 1.0 C
6 NaN c
7 0.0 cc
8 -1.0 d
In [30]: df.sort_values(by="a",ascending=False) # 降順でならべかえる
Out[30]:
a b
4 8.0 k
0 3.0 a
3 3.0 G
1 1.0 b
5 1.0 C
7 0.0 cc
8 -1.0 d
2 -5.0 A
6 NaN c
In [31]: df.sort_values(by="b",ascending=False) # b列についても同様に
Out[31]:
a b
4 8.0 k
8 -1.0 d
7 0.0 cc
6 NaN c
1 1.0 b
0 3.0 a
3 3.0 G
5 1.0 C
2 -5.0 A
In [32]: df.sort_values(by="a",na_position="first") # NaN値を先頭にもってくる
Out[32]:
a b
6 NaN c
2 -5.0 A
8 -1.0 d
7 0.0 cc
1 1.0 b
5 1.0 C
0 3.0 a
3 3.0 G
4 8.0 k
In [33]: df.sort_values(by="a",inplace=True) # 元のデータを置き換える
In [34]: df
Out[34]:
a b
2 -5.0 A
8 -1.0 d
7 0.0 cc
1 1.0 b
5 1.0 C
0 3.0 a
3 3.0 G
4 8.0 k
6 NaN c
まとめ
今回はデータの中身をソートするsort_values関数の使い方について解説しました。SeriesでもDataFrameでも同じ関数でソートできますが、by
引数の有無が決定的な違いとなってきます。
大量のデータをさばくときはソートアルゴリズムの変更を検討してみるのも良いかもしれません。