note.nkmk.me

pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと)

Date: 2018-04-06 / tags: Python, pandas

pandas.DataFrame, pandas.Seriesで、特定の条件を満たす要素の数を行・列ごとおよび全体でカウントする方法を説明する。

条件を満たす行を抽出する方法については以下の記事を参照。

また、各列ごとにユニークな要素をカウントする場合は以下の記事を参照。

ここでは、

  • 特定の条件を満たす要素数をカウントする流れ
  • pandas.DataFrameの任意の列に対してカウント
  • 複数条件の論理積(かつ)、論理和(または)と否定(でない)

について説明したあと、具体的な例として、

  • 数値に対する条件を指定してカウント
  • 文字列に対する条件を指定してカウント
  • 欠損値NaNの数、NaNでない要素の数をカウント

を示す。

例として以下のデータを使用する。

import pandas as pd

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

サンプルのcsvファイルはコチラ。

スポンサーリンク

特定の条件を満たす要素数をカウントする流れ

特定の条件を満たす要素数をカウントする流れは以下の通り。

  • 各要素を判定しbool型(True, False)のpandas.DataFrame, pandas.Seriesオブジェクトを取得
  • boolのオブジェクトをsum()メソッドでカウント
    • 列ごとにカウント: sum()
    • 行ごとにカウント: sum(axis=1)
    • 全体でカウント: values.sum()

pandas.DataFrame, pandas.Seriesオブジェクトに対して比較演算子を適用すると、各要素ごとに判定され、bool型(True, False)の同じサイズのpandas.DataFrame, pandas.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においてTrue1False0とみなされるため、bool値のオブジェクトに対して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

pandas.DataFrameおよびpandas.Seriesvalues属性でNumPy配列numpay.ndarrayとして要素全体のデータを取得できる。

pandas.DataFrameのメソッドsum()と異なり、numpy.ndarrayのメソッドsum()はデフォルトで全体の合計を算出する。したがって、boolのオブジェクトのvalues属性(numpy.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

pandas.DataFrameの任意の列に対してカウント

上の例のように、pandas.DataFrameに対して比較演算子を適用すると、全要素に対して比較演算が行われる。

任意の列に対して条件を満たす要素をカウントする場合は、[]などで列を指定して同様の処理を行えばよい。

s_bool = df['age'] < 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

行・列の選択および抽出については以下の記事を参照。

複数条件の論理積(かつ)、論理和(または)と否定(でない)

複数条件を組み合わせる場合、各条件(によって生成されるbool値のオブジェクト)を括弧()で囲んだ上で、

  • 論理積(かつ): &演算子
  • 論理和(または): |演算子

で接続する。

  • 否定(でない): ~演算子

も使用可能。

df_bool_multi = ((df == 'CA') | (df == 70))
print(df_bool_multi)
#     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_bool_multi.sum())
# name     0
# age      0
# state    3
# point    2
# dtype: int64

print(df_bool_multi.sum(axis=1))
# 0    0
# 1    1
# 2    2
# 3    1
# 4    1
# 5    0
# dtype: int64

print(df_bool_multi.values.sum())
# 5

列同士の条件を組み合わせ。

df_bool_multi_and = ((df['state'] == 'CA') & (df['age'] < 30))
print(df_bool_multi_and)
# 0    False
# 1    False
# 2     True
# 3    False
# 4     True
# 5    False
# dtype: bool

print(df_bool_multi_and.sum())
# 2

df_bool_multi_or = ((df['state'] == 'CA') | (df['age'] < 30))
print(df_bool_multi_or)
# 0     True
# 1     True
# 2     True
# 3    False
# 4     True
# 5    False
# dtype: bool

print(df_bool_multi_or.sum())
# 4

否定演算子の例。

df_bool_not = ~(df == 'CA')
print(df_bool_not)
#    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_bool_not.sum())
# name     6
# age      6
# state    3
# point    6
# dtype: int64

print(df_bool_not.sum(axis=1))
# 0    4
# 1    3
# 2    3
# 3    4
# 4    3
# 5    4
# dtype: int64

print(df_bool_not.values.sum())
# 21

数値に対する条件を指定してカウント

これまでの例でも登場しているが、数値に対しては比較演算子<, <=, >, >=, ==, !=などが使用できる。

df_num = df[['age', 'point']]
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 <= 70).sum())
# age      6
# point    4
# dtype: int64

print(((df['age'] > 20) & (df['age'] < 40)).sum())
# 3

print((df_num % 2 == 1).sum())
# age      0
# point    1
# dtype: int64

文字列に対する条件を指定してカウント

文字列に対しては比較演算子のほかpandas.Seriesの文字列メソッドstrが使用可能。

文字列メソッドには以下のようなものがある。

  • str.contains(): 特定の文字列を含む
  • str.endswith(): 特定の文字列で終わる
  • str.startswith(): 特定の文字列で始まる
  • str.match(): 正規表現のパターンに一致する

文字列メソッドはpandas.Seriesのメソッドでpandas.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を扱う例としてタイタニックの生存者のデータを使用する。Kaggleの問題からダウンロードできる。

以下のようなデータ。head()で先頭のみ表示している。

df = pd.read_csv('data/src/titanic_train.csv')

print(df.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ではない要素の数を確認するだけならinfo()メソッドで表示することができる。

info()メソッドはpandas.DataFrameのメソッドで、pandas.Seriesには無いので注意。

df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 891 entries, 0 to 890
# Data columns (total 12 columns):
# PassengerId    891 non-null int64
# Survived       891 non-null int64
# Pclass         891 non-null int64
# Name           891 non-null object
# Sex            891 non-null object
# Age            714 non-null float64
# SibSp          891 non-null int64
# Parch          891 non-null int64
# Ticket         891 non-null object
# Fare           891 non-null float64
# Cabin          204 non-null object
# Embarked       889 non-null object
# dtypes: float64(2), int64(5), object(5)
# memory usage: 83.6+ KB

以下、例はpandas.DataFrameだがpandas.Seriesでも同様の処理が可能。

欠損値NaNの数をカウントするにはisnull()メソッドを使う。

isnull()は各要素がNaNかどうかを判定するメソッド。数をカウントするにはこれまでの例と同様、さらにsum()を適用すればよい。

print(df.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.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.isnull().sum(axis=1).head())
# 0    1
# 1    0
# 2    1
# 3    0
# 4    1
# dtype: int64

print(df.isnull().values.sum())
# 866

欠損値Nanではない要素の数をpandas.Seriesやスカラー値として取得したい場合は、count()メソッドを使う。

count()sum()と同様に引数を省略すると列に対する処理、引数axis=1とすると行に対する処理となる。

print(df.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.count(axis=1).head())
# 0    11
# 1    12
# 2    11
# 3    12
# 4    11
# dtype: int64

print(df.count().sum())
# 9826

欠損値NaNを除外したり他の値に置換する場合や、行・列に欠損値NaNが含まれているかを判定する場合は、以下の記事を参照。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事