DataFrameの行や列のインデックスでソートする — Pandas入門

DataFrameでは、値でのソートはもちろん、行や列のインデックスでソートすることもできます。この記事ではインデックスでソートするsort_index()メソッドについて解説します。

本記事のサンプルコードはIPythonで実行しています。

目次

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

まとめ

データを整理するのにソートは欠かせません。今回はインデックスでソートしましたが、次の機会は値でのソートを説明したいと思います。

では、最後までご覧いただきありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

・PM、SE、SIなどを20年以上経験
・ネットワークスペシャリスト、セキュリティスペシャリストなど複数の資格を保有

目次