pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと)
pandasでDataFrame
, Series
の特定の条件を満たす要素の数を行・列ごとおよび全体でカウントする方法を説明する。
最後に紹介するように、DataFrame
とSeries
のcount()
メソッドは欠損値でない要素の数をカウントする。
条件を満たす行を抽出する方法、各列ごとにユニークな要素の数をカウントする方法については以下の記事を参照。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として以下のデータを使用する。
import pandas as pd
print(pd.__version__)
# 2.1.4
df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
特定の条件を満たす要素数をカウントする流れ
特定の条件を満たす要素数をカウントする流れは以下の通り。
- 各要素を判定し
bool
型(True
,False
)のDataFrame
,Series
を取得- 比較演算子や文字列アクセサなどを利用
sum()
メソッドでカウントDataFrame
- 列ごとにカウント:
sum()
- 行ごとにカウント:
sum(axis=1)
- 全体でカウント:
sum().sum()
またはvalues.sum()
- 列ごとにカウント:
Series
- 全体でカウント:
sum()
- 全体でカウント:
DataFrameの例
DataFrame
, Series
に対して比較演算子を適用すると、各要素ごとに判定され、同じサイズのbool
型(True
, False
)のDataFrame
, Series
が取得できる。
右辺の括弧()
は省略可能。
df_bool = (df == 'CA')
print(df_bool)
# name age state point
# 0 False False False False
# 1 False False True False
# 2 False False True False
# 3 False False False False
# 4 False False True False
# 5 False False False False
PythonにおいてTrue
は1
、False
は0
とみなされるため、sum()
メソッドで合計を算出することで条件を満たす要素の数が得られる。デフォルトは列ごと、引数axis=1
とすると行ごとのカウントとなる。
print(df_bool.sum())
# name 0
# age 0
# state 3
# point 0
# dtype: int64
print(df_bool.sum(axis=1))
# 0 0
# 1 1
# 2 1
# 3 0
# 4 1
# 5 0
# dtype: int64
DataFrame
のsum()
はSeries
を返す。さらにSeries
のsum()
を呼ぶことで、総数を得られる。
print(df_bool.sum().sum())
# 3
また、DataFrame
はvalues
属性でNumPy配列ndarray
に変換できる。
ndarray
のsum()
メソッドはデフォルトで全体の合計を算出するため、values
属性(ndarray
)からsum()
を呼ぶと条件を満たす要素の総数(全体の個数)が取得できる。
print(df_bool.values)
# [[False False False False]
# [False False True False]
# [False False True False]
# [False False False False]
# [False False True False]
# [False False False False]]
print(type(df_bool.values))
# <class 'numpy.ndarray'>
print(df_bool.values.sum())
# 3
続けて書いてもよい。
print((df == 'CA').sum())
# name 0
# age 0
# state 3
# point 0
# dtype: int64
print((df == 'CA').sum(axis=1))
# 0 0
# 1 1
# 2 1
# 3 0
# 4 1
# 5 0
# dtype: int64
print((df == 'CA').sum().sum())
# 3
print((df == 'CA').values.sum())
# 3
なお、数値と文字列の列が混在するDataFrame
に対して数値との比較演算を行うと、文字列と数値が比較されてしまいエラーとなるので注意。詳細は「数値に対する条件」の節で述べる。
Seriesの例
以下のSeries
を例とする。
s = df['age']
print(s)
# 0 24
# 1 42
# 2 18
# 3 68
# 4 24
# 5 30
# Name: age, dtype: int64
やり方はDataFrame
と同じ。Series
は一次元データなので、sum()
メソッドは総数を返す。
s_bool = (s < 25)
print(s_bool)
# 0 True
# 1 False
# 2 True
# 3 False
# 4 True
# 5 False
# Name: age, dtype: bool
print(s_bool.sum())
# 3
print((s < 25).sum())
# 3
DataFrame
の任意の行・列に対して条件を満たす要素をカウントする場合は、[]
やloc[]
, iloc[]
などで行・列を指定して同様の処理を行えばよい。
複数条件の論理積(かつ)、論理和(または)、否定(でない)
複数条件を組み合わせるには、各条件式を括弧()
で囲んだ上で、&
演算子(論理積、AND、かつ)や|
演算子(論理和、OR、または)で接続する。~
演算子(否定、NOT、でない)も使用可能。
print((df == 'CA') | (df == 70))
# name age state point
# 0 False False False False
# 1 False False True False
# 2 False False True True
# 3 False False False True
# 4 False False True False
# 5 False False False False
print(~(df == 'CA'))
# name age state point
# 0 True True True True
# 1 True True False True
# 2 True True False True
# 3 True True True True
# 4 True True False True
# 5 True True True True
print((df['state'] == 'CA') & (df['age'] < 30))
# 0 False
# 1 False
# 2 True
# 3 False
# 4 True
# 5 False
# dtype: bool
&
, |
ではなくand
, or
を使ったり、括弧を省略したりするとエラーになるので注意。
例は省略するが、bool
型(True
, False
)のDataFrame
やSeries
が取得できれば、上述のように、sum()
メソッドなどで条件を満たす要素をカウントできる。
数値に対する条件を指定してカウント
これまでの例でも登場しているが、数値に対しては比較演算子<
, <=
, >
, >=
, ==
, !=
などが使用できる。
文字列の列を含むDataFrame
に対して<
や>
などで数値と比較するとエラーになるので注意。数値列のみ抽出するにはselect_dtypes()
を使う。
# print(df < 65)
# TypeError: '<' not supported between instances of 'str' and 'int'
df_num = df.select_dtypes('number')
print(df_num)
# age point
# 0 24 64
# 1 42 92
# 2 18 70
# 3 68 70
# 4 24 88
# 5 30 57
print((df_num < 65).sum())
# age 5
# point 2
# dtype: int64
print(((df_num > 35) & (df_num < 65)).sum())
# age 1
# point 2
# dtype: int64
文字列に対する条件を指定してカウント
文字列に対しては==
や!=
のほかSeries
の文字列アクセサstr
によって以下のようなメソッドが使用可能。
str.contains()
: 特定の文字列を含むstr.endswith()
: 特定の文字列で終わるstr.startswith()
: 特定の文字列で始まるstr.match()
: 正規表現のパターンに一致する
文字列アクセサはSeries
のものでDataFrame
では使えないので注意。
df_str = df[['name', 'state']]
print(df_str)
# name state
# 0 Alice NY
# 1 Bob CA
# 2 Charlie CA
# 3 Dave TX
# 4 Ellen CA
# 5 Frank NY
print((df_str == 'NY').sum())
# name 0
# state 2
# dtype: int64
print(df_str['name'].str.endswith('e'))
# 0 True
# 1 False
# 2 True
# 3 True
# 4 False
# 5 False
# Name: name, dtype: bool
print(df_str['name'].str.endswith('e').sum())
# 3
文字列アクセサを利用して条件を満たす行を抽出する方法については以下の記事を参照。
欠損値NaNの数、NaNでない要素の数をカウント
欠損値NaN
を含む例としてタイタニックの生存者のデータを使用する。
df_titanic = pd.read_csv('data/src/titanic_train.csv')
print(df_titanic.head())
# PassengerId Survived Pclass \
# 0 1 0 3
# 1 2 1 1
# 2 3 1 3
# 3 4 1 1
# 4 5 0 3
#
# Name Sex Age SibSp \
# 0 Braund, Mr. Owen Harris male 22.0 1
# 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1
# 2 Heikkinen, Miss. Laina female 26.0 0
# 3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1
# 4 Allen, Mr. William Henry male 35.0 0
#
# Parch Ticket Fare Cabin Embarked
# 0 0 A/5 21171 7.2500 NaN S
# 1 0 PC 17599 71.2833 C85 C
# 2 0 STON/O2. 3101282 7.9250 NaN S
# 3 0 113803 53.1000 C123 S
# 4 0 373450 8.0500 NaN S
欠損値NaN
の削除や置換、判定については以下の記事を参照。
- 関連記事: pandasで欠損値NaNを削除(除外)するdropna
- 関連記事: pandasで欠損値NaNを置換(穴埋め)するfillna
- 関連記事: pandasで欠損値NaNが含まれているか判定、個数をカウント
欠損値NaNの数をカウント
欠損値NaN
の数をカウントするには、各要素がNaN
かどうかを判定するisnull()
メソッドを使う。数をカウントするには、これまでの例と同様、さらにsum()
を適用すればよい。
print(df_titanic.isnull().head())
# PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket \
# 0 False False False False False False False False False
# 1 False False False False False False False False False
# 2 False False False False False False False False False
# 3 False False False False False False False False False
# 4 False False False False False False False False False
#
# Fare Cabin Embarked
# 0 False True False
# 1 False False False
# 2 False True False
# 3 False False False
# 4 False True False
print(df_titanic.isnull().sum())
# PassengerId 0
# Survived 0
# Pclass 0
# Name 0
# Sex 0
# Age 177
# SibSp 0
# Parch 0
# Ticket 0
# Fare 0
# Cabin 687
# Embarked 2
# dtype: int64
print(df_titanic.isnull().sum(axis=1).head())
# 0 1
# 1 0
# 2 1
# 3 0
# 4 1
# dtype: int64
print(df_titanic.isnull().values.sum())
# 866
欠損値NaNでない要素の数をカウント: count()
欠損値Nan
ではない要素の数をカウントするにはcount()
メソッドを使う。sum()
と同様、引数を省略すると列、引数axis=1
とすると行に対する処理となる。
- pandas.DataFrame.count — pandas 2.1.4 documentation
- pandas.Series.count — pandas 2.1.4 documentation
print(df_titanic.count())
# PassengerId 891
# Survived 891
# Pclass 891
# Name 891
# Sex 891
# Age 714
# SibSp 891
# Parch 891
# Ticket 891
# Fare 891
# Cabin 204
# Embarked 889
# dtype: int64
print(df_titanic.count(axis=1).head())
# 0 11
# 1 12
# 2 11
# 3 12
# 4 11
# dtype: int64
print(df_titanic.count().sum())
# 9826
print(df_titanic['Age'].count())
# 714
欠損値Nan
でない要素の数を確認するだけならinfo()
メソッドで表示できる。
df_titanic.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 891 entries, 0 to 890
# Data columns (total 12 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 PassengerId 891 non-null int64
# 1 Survived 891 non-null int64
# 2 Pclass 891 non-null int64
# 3 Name 891 non-null object
# 4 Sex 891 non-null object
# 5 Age 714 non-null float64
# 6 SibSp 891 non-null int64
# 7 Parch 891 non-null int64
# 8 Ticket 891 non-null object
# 9 Fare 891 non-null float64
# 10 Cabin 204 non-null object
# 11 Embarked 889 non-null object
# dtypes: float64(2), int64(5), object(5)
# memory usage: 83.7+ KB