DataFrameでは、値でのソートはもちろん、行や列のインデックスでソートすることもできます。この記事ではインデックスでソートするsort_index()メソッドについて解説します。
DataFrameをインデックスでソートする
DataFrameの行や列のインデックスを辞書順でソートするには、sort_index()メソッドを使います。このメソッドは、デフォルトでソートした新しいDataFrameオブジェクトを返します。
はじめにサンプルコードで使用するDataFrameを作成します。
In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: data = {
...: 'a': ['A1', 'A2', 'A3', 'A4'],
...: 'b': ['B1', 'B2', 'B3', 'B4'],
...: 'c': ['C1', 'C2', 'C3', 'C4'],
...: 'd': ['D1', 'D2', 'D3', 'D4']
...: }
In [4]: df = pd.DataFrame(data, index=[1, 2, 3, 4])
In [5]: df
Out[5]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
ソートをテストするために順番を並び替えます。
In [6]: df1 = df.reindex(index=[3, 1, 4, 2])
In [7]: df1
Out[7]:
a b c d
3 A3 B3 C3 D3
1 A1 B1 C1 D1
4 A4 B4 C4 D4
2 A2 B2 C2 D2
行のインデックスでソートする
行インデックスを昇順ソート
行のインデックスでソートします。デフォルトでsort_index()は昇順でソートします。
In [8]: df2 = df1.sort_index()
In [9]: df2
Out[9]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
行インデックスを降順ソート
降順でソートするには「ascending=False」を指定します。
In [10]: df3 = df1.sort_index(ascending=False)
In [11]: df3
Out[11]:
a b c d
4 A4 B4 C4 D4
3 A3 B3 C3 D3
2 A2 B2 C2 D2
1 A1 B1 C1 D1
ソートアルゴリズムの選択
sort_index()は、ソートに使用するソートアルゴリズムを、次のいずれかから選択することができます。
- ‘quicksort’(デフォルト)
- ‘mergesort’(安定ソート)
- ‘heapsort’
- ‘stable’(安定ソート)
デフォルトのソートアルゴリズムはクイックソートです。安定ソートなアルゴリズムは‘mergesort’か‘stable’です。
安定ソートのアルゴリズムでは、同じ値の順序がソート前とソート後で変わらないことが保証されます。
次の例では安定ソートのアルゴリズムである‘mergesort’を使ってソートしています。この例のデータでは、安定ソートの効果は分かりませんが、ソートアルゴリズムの指定方法だけ覚えておいてください。
In [12]: df1.sort_index(kind='mergesort')
Out[12]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
元オブジェクトを行インデックスでソート
sort_index()メソッドは、デフォルトでソートした新しいDataFrameオブジェクトを返しますが、元のオブジェクトをソートすることもできます。それには「inplace=True」を指定します。
In [13]: df1
Out[13]:
a b c d
3 A3 B3 C3 D3
1 A1 B1 C1 D1
4 A4 B4 C4 D4
2 A2 B2 C2 D2
In [14]: df1.sort_index(inplace=True)
In [15]: df1
Out[15]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
行インデックスのNaNをソート
行インデックスにNaNがある場合、デフォルトでNaNは末尾にソートされます。行インデックスにNaNを含むDataFrameオブジェクトを用意してソートしてみましょう。
In [16]: row_nan = pd.DataFrame(df1, index=[np.nan, 1, 2, 3, 4])
In [17]: row_nan
Out[17]:
a b c d
NaN NaN NaN NaN NaN
1.0 A1 B1 C1 D1
2.0 A2 B2 C2 D2
3.0 A3 B3 C3 D3
4.0 A4 B4 C4 D4
ソートするとNaNのインデックスは末尾にソートされます。
In [18]: row_nan.sort_index()
Out[18]:
a b c d
1.0 A1 B1 C1 D1
2.0 A2 B2 C2 D2
3.0 A3 B3 C3 D3
4.0 A4 B4 C4 D4
NaN NaN NaN NaN NaN
NaNを先頭にソートしたい場合は「na_position=’first’」を指定します。
In [19]: row_nan.sort_index(na_position='first')
Out[19]:
a b c d
NaN NaN NaN NaN NaN
1.0 A1 B1 C1 D1
2.0 A2 B2 C2 D2
3.0 A3 B3 C3 D3
4.0 A4 B4 C4 D4
列のインデックスでソートする
sort_index()を使って列のインデックスでソートすることもできます。列でソートするには軸(axis=1)を指定します。axis引数のデフォルト値は0で、これは行を意味するので上述の例で引数axisは省略していました。その他の引数の使い方は行の場合と全く同じです。
はじめにソートするデータを準備します。
In [20]: df_col = df.reindex(columns=['d', 'a', 'c', 'b'])
In [21]: df_col
Out[21]:
d a c b
1 D1 A1 C1 B1
2 D2 A2 C2 B2
3 D3 A3 C3 B3
4 D4 A4 C4 B4
列インデックスを昇順ソート
列のインデックスでソートするには「axis=1」指定します。デフォルトでは昇順でソートします。
In [22]: df_col1 = df_col.sort_index(axis=1)
In [23]: df_col1
Out[23]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
列インデックスを降順ソート
降順でソートするには「ascending=False」を指定します。
In [24]: df_col2 = df_col.sort_index(axis=1, ascending=False)
In [25]: df_col2
Out[25]:
d c b a
1 D1 C1 B1 A1
2 D2 C2 B2 A2
3 D3 C3 B3 A3
4 D4 C4 B4 A4
ソートアルゴリズムの選択
ソートアルゴリズムに‘quicksort’、‘mergesort’、‘heapsort’、‘stable’が選択できるのは、行のソートのときと同様です。詳しくは行のソートの記述を参照ください。
次の例では安定ソートのアルゴリズムである‘mergesort’を使ってソートしています。
In [26]: df_col.sort_index(axis=1, kind='mergesort')
Out[26]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
元オブジェクトを列インデックスでソート
新しいDataFrameオブジェクトを作成しないで、その場でオブジェクトを修正したい場合は「inplace=True」を指定します。
In [27]: df_col.sort_index(axis=1, inplace=True)
In [28]: df_col
Out[28]:
a b c d
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
列インデックスのNaNをソート
列インデックスにNaNがある場合も、デフォルトではNaNは末尾にソートされます。列インデックスにNaNを含むDataFrameオブジェクトを用意します。
In [29]: col_nan = pd.DataFrame(df_col, columns=[np.nan, 'a', 'b', 'c', 'd'])
In [30]: col_nan
Out[30]:
NaN a b c d
1 NaN A1 B1 C1 D1
2 NaN A2 B2 C2 D2
3 NaN A3 B3 C3 D3
4 NaN A4 B4 C4 D4
デフォルトで列インデックスのNaNは末尾にソートされます。先頭にソートしたい場合は「na_position=’first’」を指定します。
In [31]: col_nan.sort_index(axis=1)
Out[31]:
a b c d NaN
1 A1 B1 C1 D1 NaN
2 A2 B2 C2 D2 NaN
3 A3 B3 C3 D3 NaN
4 A4 B4 C4 D4 NaN
In [32]: col_nan.sort_index(axis=1, na_position='first')
Out[32]:
NaN a b c d
1 NaN A1 B1 C1 D1
2 NaN A2 B2 C2 D2
3 NaN A3 B3 C3 D3
4 NaN A4 B4 C4 D4
階層型インデックス(Multiindex)のソート
sort_index()メソッドは、階層型インデックス(Multiindex)を持つDataFrameオブジェクトでも機能します。
はじめにデータを用意します。
In [64]: multi = pd.DataFrame(np.arange(16).reshape((4, 4)),
...: index=[['b', 'b', 'a', 'a'], ['2', '1', '1', '2']],
...: columns=[['b', 'b', 'a', 'a'], ['2', '1', '1', '2']])
In [65]: multi
Out[65]:
b a
2 1 1 2
b 2 0 1 2 3
1 4 5 6 7
a 1 8 9 10 11
2 12 13 14 15
axis引数を省略(あるいはaxis=0を指定)すると行インデックスでソートします。軸として「axis=1」を指定すると列インデックスでソートします。
In [66]: multi.sort_index()
Out[66]:
b a
2 1 1 2
a 1 8 9 10 11
2 12 13 14 15
b 1 4 5 6 7
2 0 1 2 3
In [67]: multi.sort_index(axis=1)
Out[67]:
a b
1 2 1 2
b 2 2 3 1 0
1 6 7 5 4
a 1 10 11 9 8
2 14 15 13 12
階層型インデックスでは、ソートする階層をlevel引数で指定できます。level引数にはレベルを表す整数か名前、あるいはそれらのリストを指定できます。インデックス階層のレベルは0から始まります。
次の例ではlevel引数に整数を指定しています。
In [68]: multi.sort_index(level=0)
Out[68]:
b a
2 1 1 2
a 1 8 9 10 11
2 12 13 14 15
b 1 4 5 6 7
2 0 1 2 3
In [69]: multi.sort_index(level=1)
Out[69]:
b a
2 1 1 2
a 1 8 9 10 11
b 1 4 5 6 7
a 2 12 13 14 15
b 2 0 1 2 3
次の例では最初にインデックスに名前を付け、level引数にはインデックスの名前を指定してソートしています。
In [70]: multi.index.set_names(['row0', 'row1'], inplace=True)
In [71]: multi.columns.set_names(['col0', 'col1'], inplace=True)
In [72]: multi
Out[72]:
col0 b a
col1 2 1 1 2
row0 row1
b 2 0 1 2 3
1 4 5 6 7
a 1 8 9 10 11
2 12 13 14 15
In [73]: multi.sort_index(level='row0')
Out[73]:
col0 b a
col1 2 1 1 2
row0 row1
a 1 8 9 10 11
2 12 13 14 15
b 1 4 5 6 7
2 0 1 2 3
In [74]: multi.sort_index(level='row1')
Out[74]:
col0 b a
col1 2 1 1 2
row0 row1
a 1 8 9 10 11
b 1 4 5 6 7
a 2 12 13 14 15
b 2 0 1 2 3
In [75]: multi.sort_index(axis=1, level='col1')
Out[75]:
col0 a b a b
col1 1 1 2 2
row0 row1
b 2 2 1 3 0
1 6 5 7 4
a 1 10 9 11 8
2 14 13 15 12
まとめ
データを整理するのにソートは欠かせません。今回はインデックスでソートしましたが、次の機会は値でのソートを説明したいと思います。
では、最後までご覧いただきありがとうございました。