Pandasにはデータの中身だけではなく、インデックスラベルやクラスラベルに対してもソートをかけることが可能です。
本記事ではsort_index
関数について
- Seriesでの使い方
- DataFrameでの使い方
- MultiIndexでの扱い方
について解説していきます。
データの中身のソートについてはsort_values関数を使いますが、この関数の使い方は以下の記事で解説しています。
Pandasで列データをソートするsort_values関数の使い方 /features/pandas-sort-values.html
sort_index関数
APIドキュメント
まずはSeriesとDataFrameで使うsort_index関数のAPIドキュメントを見ていきましょう。どちらも同じ引数をとるので使い勝手は全く一緒です。
sort_index(axis=0,level=None,ascending=True,inplace=False,kind=’quicksort’,na_position=’last’,sort_remaining=True,by=None)
params:
パラメータ名 | 型 | 概要 |
---|---|---|
axis | 0または’index’ 1または’columns’(DataFrameのみ) |
(省略可能)初期値0 インデックスラベルとカラムラベルどちらをソートするかを指定します。 |
level | intもしくはlevelの名前 intのリスト levelの名前のリスト |
(省略可能)初期値None None以外の値が指定された時、指定されたIndexの階層の値でソートを行います。 |
ascending | bool | (省略可能)初期値True Trueなら昇順でソートし、Falseなら降順でソートします。 |
inplace | bool値 | (省略可能)初期値False ソートされた結果を元のデータに反映させるかどうかを指定します。 |
kind | ‘quicksort’, ‘mergesort’, ‘heapsort’ のいずれか |
(省略可能)初期値’quicksort’ ソートする際に用いるアルゴリズムを指定します。’quicksort’が一番高速と言われています。 |
na_position | ‘first’,’last’ のいずれか |
(省略可能)初期値’last’ NaN値をどこに置くかを指定します。’first’なら先頭に、’last’なら最後尾です。 |
sort_remaining | bool値 | (省略可能)初期値True TrueでラベルがMultiIndexでソートする階層が指定されているとき、指定された階層の値を元にソートを行なったのち、他の階層の値に基づいてもソートを行います。 |
returns:
インデックスラベルかカラムラベルがソートされたSeriesまたはDataFrameが返されます
引数kind
でソートするアルゴリズムを変更できますが、ソートのアルゴリズムによる違いは以下の記事で扱っていますのでこちらを参照してください。
MultiIndexのときだけ少し扱いに慎重になる必要がありますが、それ以外の時に関しては難しい設定は特にありません。
1つずつ丁寧にみていきます。MultiIndexについては後ほど別途で解説します。
Seriesのインデックスをソートする
まずはSeriesのデータからソートしていきます。特に引数を指定しない状態で試してみます。
In [1]: import pandas as pd
In [3]: import numpy as np
In [4]: ser = pd.Series(range(6),index=[0,np.nan,-1,2,5,1])
In [5]: ser # 中身を確認
Out[5]:
0.0 0
NaN 1
-1.0 2
2.0 3
5.0 4
1.0 5
dtype: int64
In [6]: ser.sort_index() # indexの値を元にソートする
Out[6]:
-1.0 2
0.0 0
1.0 5
2.0 3
5.0 4
NaN 1
dtype: int64
先ほどは昇順で並べ替えられていましたが、降順に変更してみます。ascending=False
を指定することで変更可能です。
In [7]: ser.sort_index(ascending=False) # 降順
Out[7]:
5.0 4
2.0 3
1.0 5
0.0 0
-1.0 2
NaN 1
dtype: int64
NaN値を先頭に持っていきたい時はna_position='first'
にすれば持って来れます。
In [8]: ser.sort_index(na_position='first') # NaN値を先頭にもってくる
Out[8]:
NaN 1
-1.0 2
0.0 0
1.0 5
2.0 3
5.0 4
dtype: int64
ソートされた結果を元のデータに反映させたいというときはinplace=True
を指定します。
In [9]: ser.sort_index(inplace=True) # 元のSeriesと置き換える
In [10]: ser
Out[10]:
-1.0 2
0.0 0
1.0 5
2.0 3
5.0 4
NaN 1
dtype: int64
文字列データもソートすることができます。
In [12]: str_ser = pd.Series(range(6),index=["a","AA","b","B","cB","c"])
In [13]: str_ser
Out[13]:
a 0
AA 1
b 2
B 3
cB 4
c 5
dtype: int64
In [14]: str_ser.sort_index()
Out[14]:
AA 1
B 3
a 0
b 2
c 5
cB 4
dtype: int64
昇順のときは大文字のA~Z、小文字のa~zと並び替えられます。ascending=False
にすればこれが逆になります。
In [15]: str_ser.sort_index(ascending=False)
Out[15]:
cB 4
c 5
b 2
a 0
B 3
AA 1
dtype: int64
DataFrameのラベルをソートする
次にDataFrameで使っていきます。DataFrameでソートできるラベルはインデックスとカラムと2つになるのでそれを指定するための引数としてaxis
が存在します。
行方向(デフォルト)でソートする場合を考えます。
axis=0
もしくはaxis='index'
でソートできます。
In [17]: data = np.arange(25).reshape(5,5)
In [18]: df = pd.DataFrame(data,index=[0,3,2,1,9],columns=[1,2,4,3,0])
In [19]: df
Out[19]:
1 2 4 3 0
0 0 1 2 3 4
3 5 6 7 8 9
2 10 11 12 13 14
1 15 16 17 18 19
9 20 21 22 23 24
In [21]: df.sort_index(axis='index') # axis=0でも可。インデックスラベルをソート
Out[21]:
1 2 4 3 0
0 0 1 2 3 4
1 15 16 17 18 19
2 10 11 12 13 14
3 5 6 7 8 9
9 20 21 22 23 24
In [22]: df.sort_index(axis='columns') # axis=1でも可。カラムラベルをソート
Out[22]:
0 1 2 3 4
0 4 0 1 3 2
3 9 5 6 8 7
2 14 10 11 13 12
1 19 15 16 18 17
9 24 20 21 23 22
あとはSeriesで扱ったものと同様の使い方ができます。
In [23]: df.sort_index(axis='index',ascending=False) # インデックスラベルを降順に並べ替え
Out[23]:
1 2 4 3 0
9 20 21 22 23 24
3 5 6 7 8 9
2 10 11 12 13 14
1 15 16 17 18 19
0 0 1 2 3 4
In [31]: df_2 = pd.DataFrame(np.arange(25).reshape(5,5),index=[0,1,3,np.nan,2],columns=[0,3,1,np.nan,-1]) # 新しいDataFrameを作成する
In [32]: df_2 # インデックスとカラムラベルにそれぞれ欠損値が含まれている
Out[32]:
0.0 3.0 1.0 NaN -1.0
0.0 0 1 2 3 4
1.0 5 6 7 8 9
3.0 10 11 12 13 14
NaN 15 16 17 18 19
2.0 20 21 22 23 24
In [33]: df_2.sort_index(axis="index",na_position='first') # 欠損値を先頭に
Out[33]:
0.0 3.0 1.0 NaN -1.0
NaN 15 16 17 18 19
0.0 0 1 2 3 4
1.0 5 6 7 8 9
2.0 20 21 22 23 24
3.0 10 11 12 13 14
In [35]: df_2.sort_index(axis="columns",na_position='first') # 欠損値を先頭に
Out[35]:
NaN -1.0 0.0 1.0 3.0
0.0 3 4 0 2 1
1.0 8 9 5 7 6
3.0 13 14 10 12 11
NaN 18 19 15 17 16
2.0 23 24 20 22 21
MultiIndexの扱い
MultiIndexを使ったソートをしてみましょう。以下のcsvファイルを使います。
id,class,gender,name,state
123,A,M,Tarou,Tokyo
221,A,F,Hanako,Osaka
145,B,M,Kakeru,Osaka
155,C,F,Manaka,Nagoya
160,A,M,Tomoki,Chiba
100,A,F,Rin,Hakata
ファイルを読み込んでソートしていきます。
どの階層をソートするかはlevel
引数で指定できます。
In [2]: multi = pd.read_csv("sample_multi.csv")
In [3]: multi
Out[3]:
id class gender name state
0 123 A M Tarou Tokyo
1 221 A F Hanako Osaka
2 145 B M Kakeru Osaka
3 155 C F Manaka Nagoya
4 160 A M Tomoki Chiba
5 100 A F Rin Hakata
In [5]: multi = multi.set_index(["class","gender"]) # これでMultiIndexを作成
In [6]: multi
Out[6]:
id name state
class gender
A M 123 Tarou Tokyo
F 221 Hanako Osaka
B M 145 Kakeru Osaka
C F 155 Manaka Nagoya
A M 160 Tomoki Chiba
F 100 Rin Hakata
In [7]: multi.sort_index(level=0) # leve=0だと外側のclassインデックスが並べ替えられる
Out[7]:
id name state
class gender
A F 221 Hanako Osaka
F 100 Rin Hakata
M 123 Tarou Tokyo
M 160 Tomoki Chiba
B M 145 Kakeru Osaka
C F 155 Manaka Nagoya
In [8]: multi.sort_index(level="gender") # Indexオブジェクトの名称でも可
Out[8]:
id name state
class gender
A F 221 Hanako Osaka
F 100 Rin Hakata
C F 155 Manaka Nagoya
A M 123 Tarou Tokyo
M 160 Tomoki Chiba
B M 145 Kakeru Osaka
最後にsort_remaining
を指定します。sort_remaining=False
にすると、指定した階層以外のインデックスオブジェクトのソートを一切行いません。
In [9]: multi.sort_index(level="gender",sort_remaining=False) # 指定した階層のみソートする
Out[9]:
id name state
class gender
A F 221 Hanako Osaka
C F 155 Manaka Nagoya
A F 100 Rin Hakata
M 123 Tarou Tokyo
B M 145 Kakeru Osaka
A M 160 Tomoki Chiba
In [10]: multi.sort_index(level="gender",sort_remaining=True) # Trueだとclassの方もそのソートされた中で並べ替えられる
Out[10]:
id name state
class gender
A F 221 Hanako Osaka
F 100 Rin Hakata
C F 155 Manaka Nagoya
A M 123 Tarou Tokyo
M 160 Tomoki Chiba
B M 145 Kakeru Osaka
まとめ
今回はsort_index
関数の使い方について解説しました。変わった引数は特にありませんでしたが、MultiIndexをソートするときだけ少し気をつけましょう。