pandas.DataFrame, Seriesを順位付けするrank
pandas.DataFrame
の行・列, pandas.Series
を順位付けするにはrank()
メソッドを使う。
- pandas.DataFrame.rank — pandas 0.23.3 documentation
- pandas.Series.rank — pandas 0.23.3 documentation
pandas.DataFrame
の列やpandas.Series
を昇順・降順に並び替えるメソッドとしてsort_values()
があるが、rank()
はデータを並び替えずに各要素の順位を返す。
sort_values()
については以下の記事を参照。
ここでは以下の内容について説明する。
rank()
の基本的な使い方- 行・列を指定: 引数
axis
- 数値のみを対象: 引数
numeric_only
- 昇順・降順を指定: 引数
ascending
- 同一値(重複値)の処理を指定: 引数:
method
- 欠損値
NaN
の処理を指定: 引数na_option
- パーセンテージを取得: 引数
pct
pandas.Series
の場合
以下のpandas.DataFrame
を例とする。
import pandas as pd
df = pd.DataFrame({'col1': [50, 80, 100, 80],
'col2': [0.3, pd.np.nan, 0.1, pd.np.nan],
'col3': ['h', 'j', 'i', 'k']},
index=['a', 'b', 'c', 'd'])
print(df)
# col1 col2 col3
# a 50 0.3 h
# b 80 NaN j
# c 100 0.1 i
# d 80 NaN k
rank()の基本的な使い方
rank()
メソッドを呼ぶと、デフォルトでは各列が昇順で順位付けされる。同一値(重複値)は平均順位となり、文字列はアルファベット順に比較される。
print(df.rank())
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.5 NaN 3.0
# c 4.0 1.0 2.0
# d 2.5 NaN 4.0
行・列を指定: 引数axis
デフォルトでは列ごとに順位付けされる。
行に対して順位付けする場合は引数axis
を1
とする。この例の場合、文字列は無視して処理される。
print(df.rank(axis=1))
# col1 col2
# a 2.0 1.0
# b 1.0 NaN
# c 2.0 1.0
# d 1.0 NaN
数値のみを対象: 引数numeric_only
デフォルトでは文字列も順位付けされる。
数値のみを対象とする場合は引数numeric_only
をTrue
とする。
print(df.rank(numeric_only=True))
# col1 col2
# a 1.0 2.0
# b 2.5 NaN
# c 4.0 1.0
# d 2.5 NaN
デフォルトはnumeric_only=None
で、文字列のみの行・列は順位付けの対象となるが、例のpandas.DataFrame
を行に対して順位付けする場合のように数値と文字列が混在していると文字列を無視して処理される。
print(df.rank(axis=1))
# col1 col2
# a 2.0 1.0
# b 1.0 NaN
# c 2.0 1.0
# d 1.0 NaN
数値と文字列が混在している場合にnumeric_only=False
とするとエラーTypeError
になる。
# print(df.rank(axis=1, numeric_only=False))
# TypeError: '<' not supported between instances of 'str' and 'int'
昇順・降順を指定: 引数ascending
デフォルトでは昇順に順位付けされる。
降順にする場合は引数ascending
をFalse
とする。
print(df.rank(ascending=False))
# col1 col2 col3
# a 4.0 1.0 4.0
# b 2.5 NaN 2.0
# c 1.0 2.0 3.0
# d 2.5 NaN 1.0
同一値(重複値)の処理を指定: 引数: method
デフォルトでは同一値(重複値)がある場合、その平均順位が返される。
引数method
によって同一値(重複値)の処理を指定できる。
デフォルトはmethod='average'
。平均値が順位となる。
print(df.rank(method='average'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.5 NaN 3.0
# c 4.0 1.0 2.0
# d 2.5 NaN 4.0
method='min'
とすると最小値が順位となる。1位、2位タイ、2位タイ、4位のように、スポーツなどで馴染み深い結果。
print(df.rank(method='min'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.0 NaN 3.0
# c 4.0 1.0 2.0
# d 2.0 NaN 4.0
method='max'
とすると最大値が順位となる。
print(df.rank(method='max'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 3.0 NaN 3.0
# c 4.0 1.0 2.0
# d 3.0 NaN 4.0
method='first'
とすると同一値(重複値)は登場順に順位付けされる。method='first'
は数値のみに有効なので注意。文字列が含まれている場合はnumeric_only=True
とする。
# print(df.rank(method='first'))
# ValueError: first not supported for non-numeric data
print(df.rank(method='first', numeric_only=True))
# col1 col2
# a 1.0 2.0
# b 2.0 NaN
# c 4.0 1.0
# d 3.0 NaN
method='dense'
とするとmin
のように最小値が順位となるが、後続が詰めて順位付けされる。1位、2位タイ、2位タイ、3位のようになる。
print(df.rank(method='dense'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.0 NaN 3.0
# c 3.0 1.0 2.0
# d 2.0 NaN 4.0
欠損値NaNの処理を指定: 引数na_option
デフォルトでは欠損値NaN
は順位付けされずNaN
のまま。
引数na_option
によってNaN
の処理を指定できる。
デフォルトはna_option='keep'
。NaN
はNaN
のまま。
print(df.rank(na_option='keep'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.5 NaN 3.0
# c 4.0 1.0 2.0
# d 2.5 NaN 4.0
na_option='top'
とするとNaN
は第1位になる。NaN
が複数ある場合の処理は引数method
に従う。
print(df.rank(na_option='top'))
# col1 col2 col3
# a 1.0 4.0 1.0
# b 2.5 1.5 3.0
# c 4.0 3.0 2.0
# d 2.5 1.5 4.0
print(df.rank(na_option='top', method='min'))
# col1 col2 col3
# a 1.0 4.0 1.0
# b 2.0 1.0 3.0
# c 4.0 3.0 2.0
# d 2.0 1.0 4.0
na_option='bottom'
とするとNaN
は最下位になる。NaN
が複数ある場合の処理は引数method
に従う。
print(df.rank(na_option='bottom'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.5 3.5 3.0
# c 4.0 1.0 2.0
# d 2.5 3.5 4.0
print(df.rank(na_option='bottom', method='min'))
# col1 col2 col3
# a 1.0 2.0 1.0
# b 2.0 3.0 3.0
# c 4.0 1.0 2.0
# d 2.0 3.0 4.0
パーセンテージを取得: 引数pct
引数pct
をTrue
とすると各要素が全体の何パーセントの位置にいるかを返す。他の引数も合わせて指定可能。
print(df.rank(pct=True))
# col1 col2 col3
# a 0.250 1.0 0.25
# b 0.625 NaN 0.75
# c 1.000 0.5 0.50
# d 0.625 NaN 1.00
print(df.rank(pct=True, method='min', ascending=False, na_option='bottom'))
# col1 col2 col3
# a 1.00 0.25 1.00
# b 0.50 0.75 0.50
# c 0.25 0.50 0.75
# d 0.50 0.75 0.25
pandas.Seriesの場合
これまでの例はpandas.DataFrame
だが、pandas.Series
でも同じ。
print(df['col1'].rank(method='min', ascending=False))
# a 4.0
# b 2.0
# c 1.0
# d 2.0
# Name: col1, dtype: float64