pandasのdescribeで各列の要約統計量(平均、標準偏差など)を取得
pandasでDataFrame, Seriesのdescribe()メソッドを使うと、各列の平均や標準偏差・最大値・最小値・最頻値などの要約統計量を取得できる。
とりあえずデータの雰囲気をつかむのに便利。
- pandas.DataFrame.describe — pandas 2.1.4 documentation
- pandas.Series.describe — pandas 2.1.4 documentation
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として以下のDataFrameを使用する。
import pandas as pd
print(pd.__version__)
# 2.1.4
df = pd.DataFrame({'int': [1, 2, 3, 1],
'float': [0.1, 0.2, 0.3, float('nan')],
'str': ['X', 'Y', 'X', 'Z'],
'str_num': ['1', '2', '3', '1'],
'bool': [True, True, False, True]})
print(df)
# int float str str_num bool
# 0 1 0.1 X 1 True
# 1 2 0.2 Y 2 True
# 2 3 0.3 X 3 False
# 3 1 NaN Z 1 True
print(df.dtypes)
# int int64
# float float64
# str object
# str_num object
# bool bool
# dtype: object
describe()の基本的な使い方
Seriesのdescribe()メソッドはSeriesを返す。
print(df['float'].describe())
# count 3.00
# mean 0.20
# std 0.10
# min 0.10
# 25% 0.15
# 50% 0.20
# 75% 0.25
# max 0.30
# Name: float, dtype: float64
print(df['str'].describe())
# count 4
# unique 3
# top X
# freq 2
# Name: str, dtype: object
print(type(df['float'].describe()))
# <class 'pandas.core.series.Series'>
データ型dtypeによって算出される項目が異なる。項目の意味については後述。
- 数値列:
count,mean,std,min,25%,50%,75%,max - オブジェクト列(文字列など):
count,unique,top,freq
DataFrameのdescribe()メソッドはDataFrameを返す。
print(df.describe())
# int float
# count 4.000000 3.00
# mean 1.750000 0.20
# std 0.957427 0.10
# min 1.000000 0.10
# 25% 1.000000 0.15
# 50% 1.500000 0.20
# 75% 2.250000 0.25
# max 3.000000 0.30
print(type(df.describe()))
# <class 'pandas.core.frame.DataFrame'>
行や要素はlocやatで取得できる。
print(df.describe().loc['std'])
# int 0.957427
# float 0.100000
# Name: std, dtype: float64
print(df.describe().at['std', 'int'])
# 0.9574271077563381
様々な型の列を含むDataFrameの場合、デフォルトでは数値(整数intや浮動小数点数float)の列のみが選択され、平均meanや標準偏差stdなどの項目が算出される。
次に説明する引数include, excludeで対象とする列のデータ型を指定できる。
対象となる型を指定: 引数include, exclude
DataFrameのdescribe()で対象とするデータ型を指定するには、引数include, excludeを使う。includeには結果に含める型、excludeには結果から除外する型を指定する。列名ではなく型を指定する。
文字列など、数値以外の列を指定
数値型は'number'で表すことが可能。exclude='number'とすると数値以外の文字列型などの列の結果が算出される。
print(df.describe(exclude='number'))
# str str_num bool
# count 4 4 4
# unique 3 3 2
# top X 1 True
# freq 2 2 3
数値列を含まないDataFrameの場合は特に引数を設定しなくても対象の項目が算出される。
print(df[['str', 'str_num', 'bool']])
# str str_num bool
# 0 X 1 True
# 1 Y 2 True
# 2 X 3 False
# 3 Z 1 True
print(df[['str', 'str_num', 'bool']].describe())
# str str_num bool
# count 4 4 4
# unique 3 3 2
# top X 1 True
# freq 2 2 3
すべての型の列を指定
include='all'とすると、すべての型の列が対象となる。数値列とそれ以外の型の列で算出される項目が異なるため、算出されない項目の値は欠損値NaNとなる。
print(df.describe(include='all'))
# int float str str_num bool
# count 4.000000 3.00 4 4 4
# unique NaN NaN 3 3 2
# top NaN NaN X 1 True
# freq NaN NaN 2 2 3
# mean 1.750000 0.20 NaN NaN NaN
# std 0.957427 0.10 NaN NaN NaN
# min 1.000000 0.10 NaN NaN NaN
# 25% 1.000000 0.15 NaN NaN NaN
# 50% 1.500000 0.20 NaN NaN NaN
# 75% 2.250000 0.25 NaN NaN NaN
# max 3.000000 0.30 NaN NaN NaN
任意の型を選択・除外
引数include, excludeには任意の型を指定可能。結果が一列でもDataFrameが返る。
print(df.describe(include=int))
# int
# count 4.000000
# mean 1.750000
# std 0.957427
# min 1.000000
# 25% 1.000000
# 50% 1.500000
# 75% 2.250000
# max 3.000000
print(type(df.describe(include=int)))
# <class 'pandas.core.frame.DataFrame'>
リストで複数の型を指定できる。算出される項目は選択された型によって自動で決まる。
print(df.describe(include=[object, bool]))
# str str_num bool
# count 4 4 4
# unique 3 3 2
# top X 1 True
# freq 2 2 3
print(df.describe(exclude=['f8', 'object']))
# int bool
# count 4.000000 4
# unique NaN 2
# top NaN True
# freq NaN 3
# mean 1.750000 NaN
# std 0.957427 NaN
# min 1.000000 NaN
# 25% 1.000000 NaN
# 50% 1.500000 NaN
# 75% 2.250000 NaN
# max 3.000000 NaN
データ型はintやbool, np.float64などの型オブジェクトや、型名の文字列'int'や'bool', 'float64'、型コードの文字列'f8'(='float64')などで指定可能。詳細は以下の記事を参照。
数値列に対して頻度などを算出
例えば、男性を0、女性を1で表したり地名を数値に割り当てているカテゴリデータなど、数値型でも平均や標準偏差ではなく最頻値やその頻度を確認したい場合がある。
そのような場合は、astype()メソッドでobjectに型変換する。すべての列の型を変えることも、個別に列を指定して変えることも可能。
print(df.astype(object).describe())
# int float str str_num bool
# count 4 3.0 4 4 4
# unique 3 3.0 3 3 2
# top 1 0.1 X 1 True
# freq 2 1.0 2 2 3
print(df.astype({'int': object}).describe(exclude='number'))
# int str str_num bool
# count 4 4 4 4
# unique 3 3 3 2
# top 1 X 1 True
# freq 2 2 2 3
数字の文字列に対して平均や標準偏差などを算出
数字の文字列に対して平均や標準偏差などを算出したい場合もastype()メソッドを使う。
print(df.astype({'str_num': int, 'bool': int}).describe())
# int float str_num bool
# count 4.000000 3.00 4.000000 4.00
# mean 1.750000 0.20 1.750000 0.75
# std 0.957427 0.10 0.957427 0.50
# min 1.000000 0.10 1.000000 0.00
# 25% 1.000000 0.15 1.000000 0.75
# 50% 1.500000 0.20 1.500000 1.00
# 75% 2.250000 0.25 2.250000 1.00
# max 3.000000 0.30 3.000000 1.00
describe()の項目の意味と対応する個別メソッド
describe()で算出される項目の意味と、各項目を個別に算出するメソッドを示す。
describe()で得られるDataFrameの行をloc[]で指定すれば項目ごとの値を選択できるが、他の項目が必要なければ個別のメソッドを使うほうが無駄がない。
describe()ではいずれの項目を算出する際も欠損値NaNは除外して処理されるが、個別のメソッドではNaNを含めるかどうかを引数で指定できるものもある。
count: 欠損値NaNではない要素の個数
count()メソッドで個別に算出可能。
print(df.count())
# int 4
# float 3
# str 4
# str_num 4
# bool 4
# dtype: int64
unique: ユニークな要素の数(重複を除いた件数)
nunique()メソッドで個別に算出可能。
print(df.nunique())
# int 3
# float 3
# str 3
# str_num 3
# bool 2
# dtype: int64
top: 最頻値(mode)
mode()メソッドで個別に算出可能。
DataFrameのmode()はDataFrameを返す。頻度が同数の値がある場合は最頻値が複数になる。列ごとに最頻値の個数が異なる場合、空き部分は欠損値NaNとなる。
print(df.mode())
# int float str str_num bool
# 0 1.0 0.1 X 1 True
# 1 NaN 0.2 NaN NaN NaN
# 2 NaN 0.3 NaN NaN NaN
iloc[0]で先頭行を選択すると、各列の最頻値が少なくとも一つずつ取得できる。
print(df.mode().iloc[0])
# int 1.0
# float 0.1
# str X
# str_num 1
# bool True
# Name: 0, dtype: object
describe()の項目topも最頻値が複数ある場合にその中の一つだけを返すが、mode()の先頭行と一致するとは限らないので注意。
freq: 最頻値の頻度(出現回数)
Seriesのvalue_counts()メソッドで個別に算出可能。
print(df['str'].value_counts())
# str
# X 2
# Y 1
# Z 1
# Name: count, dtype: int64
print(df['str'].value_counts().iat[0])
# 2
各列の最頻値の頻度を取得したい場合など詳細は以下の記事を参照。
mean: 算術平均
mean()メソッドで個別に算出可能。
引数numeric_onlyをTrueとすると数値列のみが対象となる。以下のメソッドでも同じ。
print(df.mean(numeric_only=True))
# int 1.75
# float 0.20
# bool 0.75
# dtype: float64
describe()ではbool型の列は対象外だが、mean()ではTrueが1, Falseが0として扱われる。以下のメソッドでも同じ。
std: 標準偏差
標本標準偏差などと呼ばれる、n-1で割られるもの。std()メソッドで個別に算出可能。
print(df.std(numeric_only=True))
# int 0.957427
# float 0.100000
# bool 0.500000
# dtype: float64
min: 最小値
min()メソッドで個別に算出可能。
print(df.min(numeric_only=True))
# int 1
# float 0.1
# bool False
# dtype: object
max: 最大値
max()メソッドで個別に算出可能。
print(df.max(numeric_only=True))
# int 3
# float 0.3
# bool True
# dtype: object
50%: 中央値(median)
1/2分位数や50パーセンタイルなどとも呼ばれる。median()メソッドで個別に算出可能。
- 関連記事: pandasで中央値を取得するmedian
print(df.median(numeric_only=True))
# int 1.5
# float 0.2
# bool 1.0
# dtype: float64
25%, 75%: 1/4分位数、3/4分位数
第1四分位数や第3四分位数、25パーセンタイル、75パーセンタイルなどとも呼ばれる。
quantile()メソッドで個別に算出可能。算出するパーセンタイルの値を0から1の範囲でリスト指定する。
pandas 2.1.4時点で、引数numeric_onlyをTrueにしてもboolの列があるとエラーになる。
# print(df.quantile(q=[0.25, 0.75], numeric_only=True))
# TypeError: numpy boolean subtract, the `-` operator, is not supported, use the bitwise_xor, the `^` operator, or the logical_xor function instead.
ここではboolを除いたDataFrameを例とする。quantile()を使うと、最小値、第1四分位数、中央値、第3四分位数、最大値をまとめて算出できる。
print(df.iloc[:, :-1])
# int float str str_num
# 0 1 0.1 X 1
# 1 2 0.2 Y 2
# 2 3 0.3 X 3
# 3 1 NaN Z 1
print(df.iloc[:, :-1].quantile(q=[0, 0.25, 0.5, 0.75, 1], numeric_only=True))
# int float
# 0.00 1.00 0.10
# 0.25 1.00 0.15
# 0.50 1.50 0.20
# 0.75 2.25 0.25
# 1.00 3.00 0.30
describe()においても次に示す引数percentilesで算出するパーセンタイルを指定可能。
describe()で算出するパーセンタイルを指定: 引数percentiles
describe()ではデフォルトで最小値(0パーセンタイル)、中央値(50パーセンタイル)、最大値(100パーセンタイル)に加え、25パーセンタイル、75パーセンタイルが算出される。
最小値、中央値、最大値は常に算出されるが、それ以外は引数percentilesで指定できる。0から1までの範囲の値をリストで指定する。
print(df.describe(percentiles=[0.2, 0.4, 0.6, 0.8]))
# int float
# count 4.000000 3.00
# mean 1.750000 0.20
# std 0.957427 0.10
# min 1.000000 0.10
# 20% 1.000000 0.14
# 40% 1.200000 0.18
# 50% 1.500000 0.20
# 60% 1.800000 0.22
# 80% 2.400000 0.26
# max 3.000000 0.30
日時(datetime64[ns]型)の場合
pandasには日時を表す型dtypeであるdatetime64[ns]がある。
df['dt'] = pd.to_datetime(['2023-12-01', '2023-12-08', '2023-12-15', '2023-12-22'])
print(df)
# int float str str_num bool dt
# 0 1 0.1 X 1 True 2023-12-01
# 1 2 0.2 Y 2 True 2023-12-08
# 2 3 0.3 X 3 False 2023-12-15
# 3 1 NaN Z 1 True 2023-12-22
print(df.dtypes)
# int int64
# float float64
# str object
# str_num object
# bool bool
# dt datetime64[ns]
# dtype: object
以前のバージョンではdatetime64[ns]型の列に対してはcount, unique, top, freqの項目に加えてfirst(最初の日時)とlast(最後の日時)の項目が算出されていた。
pandas 2.1.4時点では数値列と同様に扱われる。minとmaxがfirstとlastに相当する。countやuniqueを算出したい場合は上述のようにastype()で型変換すればよい。
print(df.describe())
# int float dt
# count 4.000000 3.00 4
# mean 1.750000 0.20 2023-12-11 12:00:00
# min 1.000000 0.10 2023-12-01 00:00:00
# 25% 1.000000 0.15 2023-12-06 06:00:00
# 50% 1.500000 0.20 2023-12-11 12:00:00
# 75% 2.250000 0.25 2023-12-16 18:00:00
# max 3.000000 0.30 2023-12-22 00:00:00
# std 0.957427 0.10 NaN
print(df.astype(object).describe())
# int float str str_num bool dt
# count 4 3.0 4 4 4 4
# unique 3 3.0 3 3 2 4
# top 1 0.1 X 1 True 2023-12-01 00:00:00
# freq 2 1.0 2 2 3 1
日時に対するパーセンタイルについては以下の記事を参照。