pandasのdescribeで各列の要約統計量(平均、標準偏差など)を取得

Modified: | Tags: Python, pandas

pandasでDataFrame, Seriesdescribe()メソッドを使うと、各列の平均や標準偏差・最大値・最小値・最頻値などの要約統計量を取得できる。

とりあえずデータの雰囲気をつかむのに便利。

本記事のサンプルコードの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()の基本的な使い方

Seriesdescribe()メソッドは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

DataFramedescribe()メソッドは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'>

行や要素はlocatで取得できる。

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

DataFramedescribe()で対象とするデータ型を指定するには、引数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

データ型はintbool, 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()メソッドで個別に算出可能。

DataFramemode()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: 最頻値の頻度(出現回数)

Seriesvalue_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_onlyTrueとすると数値列のみが対象となる。以下のメソッドでも同じ。

print(df.mean(numeric_only=True))
# int      1.75
# float    0.20
# bool     0.75
# dtype: float64

describe()ではbool型の列は対象外だが、mean()ではTrue1, False0として扱われる。以下のメソッドでも同じ。

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()メソッドで個別に算出可能。

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_onlyTrueにしても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時点では数値列と同様に扱われる。minmaxfirstlastに相当する。countuniqueを算出したい場合は上述のように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

日時に対するパーセンタイルについては以下の記事を参照。

関連カテゴリー

関連記事