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

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

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ファイルを使います。

sample_multi.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をソートするときだけ少し気をつけましょう。

参考