pandasで分位数・パーセンタイルを取得するquantile

pandas.DataFrame, pandas.Seriesの分位数・パーセンタイルを取得するにはquantile()メソッドを使います。

pandas.DataFrame.quantile — pandas 0.24.2 documentation

分位数・パーセンタイルの定義は以下の通り。

実数(0.0 ~ 1.0)に対し、q 分位数 (q-quantile) は、分布を q : 1 - q に分割する値であります。 ... q/100分位数を、q パーセンタイルという。 分位数 - Wikipedia

例えば1/4分位数は25パーセンタイルと同じ。 上記Wikipediaのページにも記載されているように、1/4分位数を第1四分位数、3/4分位数を第3四分位数と呼ぶなど、特別な名称を持つ分位数もあります。 ここでは以下の内容について説明します。

quantile()の基本的な使い方 取得する分位数・パーセンタイルを指定: 引数q 補間方法を指定: 引数interpolation 補間方法によるデータ型dtypeの違い

行・列を指定: 引数axis 数値以外も対象に指定: 引数numeric_only 日時datetime型の場合

四分位数を含む要約統計量を算出するメソッドdescribe()もあります。データの概観をつかむためならこちらのほうが便利。

また、中央値(1/2分位数、50パーセンタイル)だけが必要であればmedian()でもよい。

quantile()の基本的な使い方

以下のpandas.DataFrameを例とします。

import pandas as pd

df = pd.DataFrame({'col_1': range(11),
                   'col_2': [i ** 2 for i in range(11)],
                   'col_3': list('abcdefghijk')})

print(df)
#     col_1  col_2 col_3
# 0       0      0     a
# 1       1      1     b
# 2       2      4     c
# 3       3      9     d
# 4       4     16     e
# 5       5     25     f
# 6       6     36     g
# 7       7     49     h
# 8       8     64     i
# 9       9     81     j
# 10     10    100     k

デフォルトではquantile()は数値列の中央値(1/2分位数、50パーセンタイル)をpandas.Seriesで返す。数値以外の列は無視される。

print(df.quantile())
# col_1     5.0
# col_2    25.0
# Name: 0.5, dtype: float64

print(type(df.quantile()))
# <class 'pandas.core.series.Series'>

pandas.Seriesからquantile()を呼んだ場合は、その中央値が浮動小数点数floatや整数intで返される。

print(df['col_1'].quantile())
# 5.0

print(type(df['col_1'].quantile()))
# <class 'float'>

要素の型がどうなるかは元のデータ型および後述の引数interpolationの設定によって異なる。

取得する分位数・パーセンタイルを指定: 引数q

第一引数qに取得したい分位・パーセントを0.0 ~ 1.0で指定します。

print(df.quantile(0.2))
# col_1    2.0
# col_2    4.0
# Name: 0.2, dtype: float64

リストで複数指定も可能。この場合の戻り値はpandas.DataFrameとなります。

print(df.quantile([0, 0.25, 0.5, 0.75, 1.0]))
#       col_1  col_2
# 0.00    0.0    0.0
# 0.25    2.5    6.5
# 0.50    5.0   25.0
# 0.75    7.5   56.5
# 1.00   10.0  100.0

print(type(df.quantile([0, 0.25, 0.5, 0.75, 1.0])))
# <class 'pandas.core.frame.DataFrame'>

pandas.Seriesで複数指定すると戻り値はpandas.Series。

print(df['col_1'].quantile([0, 0.25, 0.5, 0.75, 1.0]))
# 0.00     0.0
# 0.25     2.5
# 0.50     5.0
# 0.75     7.5
# 1.00    10.0
# Name: col_1, dtype: float64

print(type(df['col_1'].quantile([0, 0.25, 0.5, 0.75, 1.0])))
# <class 'pandas.core.series.Series'>

補間方法を指定: 引数interpolation

値の補間方法は引数interpolationで指定します。 デフォルトはinterpolation='linear'で、前後の値から線形補間した値が使われる。

print(df.quantile(0.21))
# col_1    2.1
# col_2    4.5
# Name: 0.21, dtype: float64

print(df.quantile(0.21, interpolation='linear'))
# col_1    2.1
# col_2    4.5
# Name: 0.21, dtype: float64

'lower'は小さい方の値、'higher'は大きい方の値、'nearest'は近い方の値がそのまま使われる。

print(df.quantile(0.21, interpolation='lower'))
# col_1    2
# col_2    4
# Name: 0.21, dtype: int64

print(df.quantile(0.21, interpolation='higher'))
# col_1    3
# col_2    9
# Name: 0.21, dtype: int64

print(df.quantile(0.21, interpolation='nearest'))
# col_1    2
# col_2    4
# Name: 0.21, dtype: int64

'midpoint'は前後の値の中間の値(平均値)となります。

print(df.quantile(0.21, interpolation='midpoint'))
# col_1    2.5
# col_2    6.5
# Name: 0.21, dtype: float64

補間方法によるデータ型dtypeの違い

デフォルトは線形補間で除算が行われるため、元のデータ型dtypeが整数intの場合は浮動小数点数floatに変換される。元の値と等しい値でもデータ型が変わるので注意。

print(df.quantile(0.2))
# col_1    2.0
# col_2    4.0
# Name: 0.2, dtype: float64

'lower'、'higher'、'nearest'の場合は元の値がそのまま使われるためデータ型もそのまま。

print(df.quantile(0.2, interpolation='lower'))
# col_1    2
# col_2    4
# Name: 0.2, dtype: int64

行・列を指定: 引数axis

デフォルトは列ごとに処理されるが、引数axis=1とすると行ごとの処理となります。この場合も数値以外の列は無視される。

print(df.quantile(axis=1))
# 0      0.0
# 1      1.0
# 2      3.0
# 3      6.0
# 4     10.0
# 5     15.0
# 6     21.0
# 7     28.0
# 8     36.0
# 9     45.0
# 10    55.0
# Name: 0.5, dtype: float64

数値以外も対象に指定: 引数numeric_only

これまでの例のように、デフォルトでは数値以外の列は無視される。 引数numeric_only=Falseとすると数値以外の列も対象となります。 ただし、例えば文字列の場合は線形補間ができないため、デフォルトのinterpolation='linear'だとエラーとなります。

# print(df.quantile(numeric_only=False))
# TypeError: can't multiply sequence by non-int of type 'float'

'lower'、'higher'、'nearest'だと辞書順に従って前後いずれかの値となります。

print(df.quantile(numeric_only=False, interpolation='lower'))
# col_1     5
# col_2    25
# col_3     f
# Name: 0.5, dtype: object

print(df.quantile(0.25, numeric_only=False, interpolation='lower'))
# col_1    2
# col_2    4
# col_3    c
# Name: 0.25, dtype: object

print(df.quantile(0.25, numeric_only=False, interpolation='higher'))
# col_1    3
# col_2    9
# col_3    d
# Name: 0.25, dtype: object

日時datetime型の場合

文字列を対象とすることはほとんどないが、日時datetime型の場合は便利。 例として、以下のように列の値を日時datetime型とします。

df['col_3'] = pd.date_range('2019-01-01', '2019-01-11')

print(df)
#     col_1  col_2      col_3
# 0       0      0 2019-01-01
# 1       1      1 2019-01-02
# 2       2      4 2019-01-03
# 3       3      9 2019-01-04
# 4       4     16 2019-01-05
# 5       5     25 2019-01-06
# 6       6     36 2019-01-07
# 7       7     49 2019-01-08
# 8       8     64 2019-01-09
# 9       9     81 2019-01-10
# 10     10    100 2019-01-11

print(df.dtypes)
# col_1             int64
# col_2             int64
# col_3    datetime64[ns]
# dtype: object

デフォルトでは日時の列は無視されるが、引数numeric_only=Falseとすると処理の対象となります。

print(df.quantile())
# col_1     5.0
# col_2    25.0
# Name: 0.5, dtype: float64

print(df.quantile(numeric_only=False))
# col_1                      5
# col_2                     25
# col_3    2019-01-06 00:00:00
# Name: 0.5, dtype: object

引数interpolationに応じて正しく補間される。

print(df.quantile(0.25, numeric_only=False))
# col_1                    2.5
# col_2                    6.5
# col_3    2019-01-03 12:00:00
# Name: 0.25, dtype: object

print(df.quantile(0.25, numeric_only=False, interpolation='lower'))
# col_1                      2
# col_2                      4
# col_3    2019-01-03 00:00:00
# Name: 0.25, dtype: object

pandas.DataFrame, pandas.Seriesを時系列データとして処理するための方法は以下の記事を参照。

シェア

関連カテゴリー

Python pandas

Python, pandas, seabornでペアプロット図(散布図行列)を作成 pandas.DataFrameの行を条件で抽出するquery pandasのオプション設定を確認・変更する方法 pandasで時系列データをリサンプリングするresample, asfreq pandas.DataFrame, Seriesのインデックスを振り直すreset_index pandasでクリップボードの中身をDataFrameとして取得するread_clipboard pandas.DataFrame, Seriesを順位付けするrank pandasで行・列ごとの最頻値を取得するmode pandasで特定の文字列を含む行を抽出(完全一致、部分一致) pandasでstack, unstack, pivotを使ってデータを整形 pandas.DataFrame, SeriesとNumPy配列ndarrayを相互に変換 pandasで欠損値NaNを除外(削除)・置換(穴埋め)・抽出 pandas.DataFrameの行と列を入れ替える(転置) pandas参考書『Python for Data Analysis, 2nd Edition』

Last Updated: 6/26/2019, 10:34:03 PM