【Pandas DataFrame】並び替え(ソート) [sort_index, sort_values]

 ※ 本記事は広告・プロモーションを含みます。
Pandas

たっきん(Twitter)です!

今回は、DataFrameのデータの並び替え(ソート)方法について説明していきます。

DataFrameを扱っているとソートする機会も結構多いため、データのソート方法についてもここでしっかりと押さえておきましょう!

データをソートするにはsort_index(), sort_values()の2つのメソッド(関数)が用意されており、用途によって使い分けます。

メソッド(関数)用途
sort_index()行ラベル(インデックス)のソート
sort_values()列データのソート

以降は次のDataFrameを使ってソート操作を説明していきます。

import pandas as pd

data = [
    [104, "ccc", 179.2, 61.6],
    [105, "aaa", 198.6, 54.8],
    [102, "eee", 158.1, 58.0],
    [101, "bbb", 179.3, 60.4],
    [103, "ddd", 167.9, 73.9],
]

df = pd.DataFrame(data, columns=["id", "name", "height", "weight"])
df.set_index("id", inplace=True)
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""
Pandasに関する記事を多数書いてます

行ラベルのソート :sort_index()

行ラベル(インデックス)をソートする場合はsort_index()を使用します。

昇順でソートするか、降順でソートするかは引数ascendingで指定します。

  • 昇順にソート → ascending=True
  • 降順にソート → ascending=False

引数ascendingはデフォルトでTrueなので、引数でascendingを指定しない場合は昇順でソートされます。

また、ソート後のデータは返り値として受け取ります。(このとき、元データは変更されません)

# 元データの確認
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""

# 昇順にソートする
df_asc = df.sort_index(ascending=True)
# df_asc = df.sort_index() と記述してもOK.
print(df_asc)
"""
昇順ソート
 ↓
    name  height  weight
id                      
101  bbb   179.3    60.4
102  eee   158.1    58.0
103  ddd   167.9    73.9
104  ccc   179.2    61.6
105  aaa   198.6    54.8
"""

# 元データの確認(元データは変更されてない)
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""

# 降順にソートする
df_des = df.sort_index(ascending=False)
print(df_des)
"""
降順ソート
 ↓
    name  height  weight
id                      
105  aaa   198.6    54.8
104  ccc   179.2    61.6
103  ddd   167.9    73.9
102  eee   158.1    58.0
101  bbb   179.3    60.4
"""

変更後のデータを返り値で受け取るのではなく、元データ自身を変更したい場合があります。

この場合は引数にinplace=Trueを指定します。

inplace=Trueが指定された場合、返り値が返されなくなり、元データが変更されます。

# 元データの確認
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""

# 昇順にソートする(元データを変更)
df.sort_index(ascending=True, inplace=True)

# 元データの確認
print(df)
"""
昇順ソート
 ↓
    name  height  weight
id                      
101  bbb   179.3    60.4
102  eee   158.1    58.0
103  ddd   167.9    73.9
104  ccc   179.2    61.6
105  aaa   198.6    54.8
"""

列データのソート :sort_values()

列データをソートする場合はsort_values()を使用します。

ソートしたい列は第1引数「ラベル名」で指定します。

昇順降順でソートするかは引数ascending、元データを変更するか否かは引数inplaceで指定するのですが、指定方法はsort_index()と同じになるので、詳細はsort_index()の章を参照してください。

# 元データの確認
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""

# 列ラベル"name"を昇順にソートする
df_name_asc = df.sort_values("name", ascending=True)
# df_name_asc = df.sort_values("name") と記述してもOK.
print(df_name_asc)
"""
   昇順ソート
      ↓
    name  height  weight
id                      
105  aaa   198.6    54.8
101  bbb   179.3    60.4
104  ccc   179.2    61.6
103  ddd   167.9    73.9
102  eee   158.1    58.0
"""

# 元データの確認(元データは変更されてない)
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""

# 列ラベル"weight"を降順にソートする
df_weight_des = df.sort_values("weight", ascending=False)
print(df_weight_des)
"""
                  降順ソート
                     ↓
    name  height  weight
id                      
103  ddd   167.9    73.9
104  ccc   179.2    61.6
101  bbb   179.3    60.4
102  eee   158.1    58.0
105  aaa   198.6    54.8
"""

inplace=True指定で元データを変更する場合のコードです。

# 元データの確認
print(df)
"""
    name  height  weight
id                      
104  ccc   179.2    61.6
105  aaa   198.6    54.8
102  eee   158.1    58.0
101  bbb   179.3    60.4
103  ddd   167.9    73.9
"""

# 昇順にソートする(元データを変更)
df.sort_values("name", ascending=True, inplace=True)

# 元データの確認
print(df)
"""
   昇順ソート
      ↓
    name  height  weight
id                      
105  aaa   198.6    54.8
101  bbb   179.3    60.4
104  ccc   179.2    61.6
103  ddd   167.9    73.9
102  eee   158.1    58.0
"""

【注意】日付データのソート

ソート対象は数値や文字列だけでなく、日付をソートしたい場合がありますが、その場合は少し注意が必要です。

日付をソートする場合、日付を文字列型で設定していると、正しくソートされません。

以下のコードは日付を文字列で定義し、DataFrameの行ラベル(インデックス)に設定後、sort_index()で日付を昇順ソートした結果になります。

import pandas as pd

ohlc_data = [
    # 日付を文字列型で定義
    #    ↓
    ["2020/4/6", 108.799, 119.109, 98.514, 108.854],
    ["2020/4/17", 107.806, 118.053, 97.354, 107.663],
    ["2020/4/2", 107.191, 118.104, 97.028, 107.922],
    ["2020/4/12", 107.488, 118.092, 97.172, 107.935],
    ["2020/4/22", 106.750, 117.506, 96.414, 107.249],
    ["2020/4/1", 107.607, 117.952, 96.929, 107.191],
    ["2020/4/19", 107.624, 117.650, 97.000, 107.278],
    ["2020/4/10", 107.803, 117.811, 96.990, 107.235],
    ["2020/4/15", 107.682, 117.904, 97.289, 107.782],
    ["2020/4/3", 107.922, 118.688, 97.811, 108.578],
    ["2020/4/7", 108.854, 119.071, 98.218, 108.545],
    ["2020/4/11", 107.235, 117.911, 96.934, 107.488],
    ["2020/4/23", 107.242, 117.414, 96.614, 106.966],
    ["2020/4/20", 107.251, 117.347, 96.567, 106.880],
    ["2020/4/16", 107.838, 117.950, 97.523, 107.758],
    ["2020/4/4", 108.432, 119.393, 98.403, 109.252],
    ["2020/4/18", 107.640, 117.769, 97.380, 107.553],
    ["2020/4/9", 108.453, 118.569, 97.510, 107.803],
    ["2020/4/21", 106.884, 116.925, 96.367, 106.757],
    ["2020/4/5", 109.252, 119.294, 98.680, 108.799],
    ["2020/4/14", 107.589, 117.958, 97.517, 107.638],
    ["2020/4/13", 107.935, 118.111, 97.309, 107.598],
    ["2020/4/8", 108.545, 118.615, 98.341, 108.515],
]

df = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high", "low", "close"])

# 日付を行ラベル(インデックス)に設定
df.set_index("datetime", inplace=True)

# DataFrameの確認
print(df)
"""
              open     high     low    close
datetime                                    
2020/4/6   108.799  119.109  98.514  108.854
2020/4/17  107.806  118.053  97.354  107.663
2020/4/2   107.191  118.104  97.028  107.922
2020/4/12  107.488  118.092  97.172  107.935
2020/4/22  106.750  117.506  96.414  107.249
2020/4/1   107.607  117.952  96.929  107.191
2020/4/19  107.624  117.650  97.000  107.278
2020/4/10  107.803  117.811  96.990  107.235
2020/4/15  107.682  117.904  97.289  107.782
2020/4/3   107.922  118.688  97.811  108.578
2020/4/7   108.854  119.071  98.218  108.545
2020/4/11  107.235  117.911  96.934  107.488
2020/4/23  107.242  117.414  96.614  106.966
2020/4/20  107.251  117.347  96.567  106.880
2020/4/16  107.838  117.950  97.523  107.758
2020/4/4   108.432  119.393  98.403  109.252
2020/4/18  107.640  117.769  97.380  107.553
2020/4/9   108.453  118.569  97.510  107.803
2020/4/21  106.884  116.925  96.367  106.757
2020/4/5   109.252  119.294  98.680  108.799
2020/4/14  107.589  117.958  97.517  107.638
2020/4/13  107.935  118.111  97.309  107.598
"""

# 日付のデータ型の確認
print(df.index[0])
"""
2020/4/6
"""
print(type(df.index[0]))
"""
<class 'str'>
"""

# 日付で昇順ソート
df_asc = df.sort_index(ascending=True)
print(df_asc)
"""
昇順ソート(文字列型だと正しくソートされない)
   ↓
              open     high     low    close
datetime                                    
2020/4/1   107.607  117.952  96.929  107.191
2020/4/10  107.803  117.811  96.990  107.235
2020/4/11  107.235  117.911  96.934  107.488
2020/4/12  107.488  118.092  97.172  107.935
2020/4/13  107.935  118.111  97.309  107.598
2020/4/14  107.589  117.958  97.517  107.638
2020/4/15  107.682  117.904  97.289  107.782
2020/4/16  107.838  117.950  97.523  107.758
2020/4/17  107.806  118.053  97.354  107.663
2020/4/18  107.640  117.769  97.380  107.553
2020/4/19  107.624  117.650  97.000  107.278
2020/4/2   107.191  118.104  97.028  107.922
2020/4/20  107.251  117.347  96.567  106.880
2020/4/21  106.884  116.925  96.367  106.757
2020/4/22  106.750  117.506  96.414  107.249
2020/4/23  107.242  117.414  96.614  106.966
2020/4/3   107.922  118.688  97.811  108.578
2020/4/4   108.432  119.393  98.403  109.252
2020/4/5   109.252  119.294  98.680  108.799
2020/4/6   108.799  119.109  98.514  108.854
2020/4/7   108.854  119.071  98.218  108.545
2020/4/8   108.545  118.615  98.341  108.515
2020/4/9   108.453  118.569  97.510  107.803
"""

日付を正しくソートするには日付データをdatetime型で設定しましょう!

以下、datetime型で日付を定義し、同じように昇順ソートした結果になります。

import pandas as pd
import datetime as dt

ohlc_data = [
    # 日付をdatetime型で定義
    #    ↓
    [dt.date(2020, 4, 6), 108.799, 119.109, 98.514, 108.854],
    [dt.date(2020, 4, 17), 107.806, 118.053, 97.354, 107.663],
    [dt.date(2020, 4, 2), 107.191, 118.104, 97.028, 107.922],
    [dt.date(2020, 4, 12), 107.488, 118.092, 97.172, 107.935],
    [dt.date(2020, 4, 22), 106.750, 117.506, 96.414, 107.249],
    [dt.date(2020, 4, 1), 107.607, 117.952, 96.929, 107.191],
    [dt.date(2020, 4, 19), 107.624, 117.650, 97.000, 107.278],
    [dt.date(2020, 4, 10), 107.803, 117.811, 96.990, 107.235],
    [dt.date(2020, 4, 15), 107.682, 117.904, 97.289, 107.782],
    [dt.date(2020, 4, 3), 107.922, 118.688, 97.811, 108.578],
    [dt.date(2020, 4, 7), 108.854, 119.071, 98.218, 108.545],
    [dt.date(2020, 4, 11), 107.235, 117.911, 96.934, 107.488],
    [dt.date(2020, 4, 23), 107.242, 117.414, 96.614, 106.966],
    [dt.date(2020, 4, 20), 107.251, 117.347, 96.567, 106.880],
    [dt.date(2020, 4, 16), 107.838, 117.950, 97.523, 107.758],
    [dt.date(2020, 4, 4), 108.432, 119.393, 98.403, 109.252],
    [dt.date(2020, 4, 18), 107.640, 117.769, 97.380, 107.553],
    [dt.date(2020, 4, 9), 108.453, 118.569, 97.510, 107.803],
    [dt.date(2020, 4, 21), 106.884, 116.925, 96.367, 106.757],
    [dt.date(2020, 4, 5), 109.252, 119.294, 98.680, 108.799],
    [dt.date(2020, 4, 14), 107.589, 117.958, 97.517, 107.638],
    [dt.date(2020, 4, 13), 107.935, 118.111, 97.309, 107.598],
    [dt.date(2020, 4, 8), 108.545, 118.615, 98.341, 108.515],
]

df = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high", "low", "close"])

# 日付を行ラベル(インデックス)に設定
df.set_index("datetime", inplace=True)

# DataFrameの確認
print(df)
"""
               open     high     low    close
datetime                                     
2020-04-06  108.799  119.109  98.514  108.854
2020-04-17  107.806  118.053  97.354  107.663
2020-04-02  107.191  118.104  97.028  107.922
2020-04-12  107.488  118.092  97.172  107.935
2020-04-22  106.750  117.506  96.414  107.249
2020-04-01  107.607  117.952  96.929  107.191
2020-04-19  107.624  117.650  97.000  107.278
2020-04-10  107.803  117.811  96.990  107.235
2020-04-15  107.682  117.904  97.289  107.782
2020-04-03  107.922  118.688  97.811  108.578
2020-04-07  108.854  119.071  98.218  108.545
2020-04-11  107.235  117.911  96.934  107.488
2020-04-23  107.242  117.414  96.614  106.966
2020-04-20  107.251  117.347  96.567  106.880
2020-04-16  107.838  117.950  97.523  107.758
2020-04-04  108.432  119.393  98.403  109.252
2020-04-18  107.640  117.769  97.380  107.553
2020-04-09  108.453  118.569  97.510  107.803
2020-04-21  106.884  116.925  96.367  106.757
2020-04-05  109.252  119.294  98.680  108.799
2020-04-14  107.589  117.958  97.517  107.638
2020-04-13  107.935  118.111  97.309  107.598
2020-04-08  108.545  118.615  98.341  108.515
"""

# 日付のデータ型の確認
print(df.index[0])
"""
2020-04-06
"""
print(type(df.index[0]))
"""
<class 'datetime.date'>
"""

# 日付で昇順ソート
df_asc = df.sort_index(ascending=True)
print(df_asc)
"""
昇順ソート(datetime型だと正しくソートされる)
   ↓
               open     high     low    close
datetime                                     
2020-04-01  107.607  117.952  96.929  107.191
2020-04-02  107.191  118.104  97.028  107.922
2020-04-03  107.922  118.688  97.811  108.578
2020-04-04  108.432  119.393  98.403  109.252
2020-04-05  109.252  119.294  98.680  108.799
2020-04-06  108.799  119.109  98.514  108.854
2020-04-07  108.854  119.071  98.218  108.545
2020-04-08  108.545  118.615  98.341  108.515
2020-04-09  108.453  118.569  97.510  107.803
2020-04-10  107.803  117.811  96.990  107.235
2020-04-11  107.235  117.911  96.934  107.488
2020-04-12  107.488  118.092  97.172  107.935
2020-04-13  107.935  118.111  97.309  107.598
2020-04-14  107.589  117.958  97.517  107.638
2020-04-15  107.682  117.904  97.289  107.782
2020-04-16  107.838  117.950  97.523  107.758
2020-04-17  107.806  118.053  97.354  107.663
2020-04-18  107.640  117.769  97.380  107.553
2020-04-19  107.624  117.650  97.000  107.278
2020-04-20  107.251  117.347  96.567  106.880
2020-04-21  106.884  116.925  96.367  106.757
2020-04-22  106.750  117.506  96.414  107.249
2020-04-23  107.242  117.414  96.614  106.966
"""

参考

スポンサーリンク

コメント

タイトルとURLをコピーしました