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でソートするアルゴリズムを変更できますが、ソートのアルゴリズムによる違いは以下の記事で扱っていますのでこちらを参照してください。

NumPyのソート関数np.sortとnp.argsortの使い方 /features/numpy-sort.html#kindパラメータで指定可能なquicksort-mergesort-heapsortについて

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引数の有無が決定的な違いとなってきます。

大量のデータをさばくときはソートアルゴリズムの変更を検討してみるのも良いかもしれません。

参考