DataFrame.allの全て:Pandasでの真偽値判定、数値・NaNの扱い、実践例

2025-06-06

pandas.DataFrame.all は、pandas の DataFrame オブジェクトが持つメソッドの一つで、全ての要素が真であるかどうかを評価するために使用されます。ブール値(True/False)を含む DataFrame に対して非常に有用ですが、数値データに対しても「0(ゼロ)」を False、それ以外の非ゼロの値を True と見なして評価することができます。

このメソッドは、デフォルトでは各列(axis=0)に対して操作を行い、その結果を Series として返します。

主な引数

  • skipna: 欠損値(NaN)を無視するかどうかを指定します。

    • True(デフォルト): 欠損値は無視されます。つまり、欠損値がある行/列でも、それ以外の全ての値が True であれば結果は True になります。
    • False: 欠損値があると、その行/列の評価結果は False になります(欠損値自体が True ではないため)。
  • bool_only: ブール値(True/False)の列のみを評価対象とするかどうかを指定します。

    • True: ブール値の列のみを評価します。他のデータ型の列はスキップされます。
    • False(デフォルト): 全ての列を評価します。非ブール値の列の場合、非ゼロの値を True、ゼロを False と見なします。
  • axis: 評価を行う軸を指定します。

    • 0 または 'index'(デフォルト): 各列に対して評価し、結果を Series として返します。
    • 1 または 'columns' : 各行に対して評価し、結果を Series として返します。

動作の例

ブール値の DataFrame での例

import pandas as pd

data_bool = {
    'col1': [True, True, True],
    'col2': [True, False, True],
    'col3': [True, True, True]
}
df_bool = pd.DataFrame(data_bool)
print("ブール値DataFrame:\n", df_bool)

# 各列で全ての値がTrueか
print("\ndf_bool.all():\n", df_bool.all())
# 出力:
# col1    True  (全ての要素がTrue)
# col2    False (Falseが含まれる)
# col3    True  (全ての要素がTrue)
# dtype: bool

# 各行で全ての値がTrueか
print("\ndf_bool.all(axis=1):\n", df_bool.all(axis=1))
# 出力:
# 0     True  (1行目の全ての要素がTrue)
# 1     False (2行目のcol2がFalse)
# 2     True  (3行目の全ての要素がTrue)
# dtype: bool

数値データを含む DataFrame での例

import pandas as pd

data_num = {
    'A': [1, 2, 3],
    'B': [1, 0, 5], # 0が含まれる
    'C': [10, 20, 30]
}
df_num = pd.DataFrame(data_num)
print("\n数値DataFrame:\n", df_num)

# 各列で全ての値が非ゼロか
print("\ndf_num.all():\n", df_num.all())
# 出力:
# A     True  (全ての要素が非ゼロ)
# B     False (0が含まれる)
# C     True  (全ての要素が非ゼロ)
# dtype: bool

欠損値(NaN)を含む DataFrame での例

import pandas as pd
import numpy as np

data_nan = {
    'X': [True, True, np.nan],
    'Y': [True, False, True],
    'Z': [True, True, True]
}
df_nan = pd.DataFrame(data_nan)
print("\nNaNを含むDataFrame:\n", df_nan)

# skipna=True (デフォルト) の場合
print("\ndf_nan.all(skipna=True):\n", df_nan.all(skipna=True))
# 出力:
# X     True  (NaNは無視されるので、残りのTrueが評価される)
# Y     False (Falseが含まれる)
# Z     True  (全ての要素がTrue)
# dtype: bool

# skipna=False の場合
print("\ndf_nan.all(skipna=False):\n", df_nan.all(skipna=False))
# 出力:
# X     False (NaNはFalseと見なされるため)
# Y     False (Falseが含まれる)
# Z     True  (全ての要素がTrue)
# dtype: bool


DataFrame.all() 自体が直接的にエラーを発生させることは比較的少ないですが、その入力データや、結果をどのように解釈・利用するかによって、問題が発生することがあります。

データ型に関する誤解

問題
DataFrame.all() は、数値データの場合、0をFalse、非ゼロの値をTrueと評価します。この挙動を誤解していると、期待しない結果になることがあります。例えば、全ての数値が0ではないことを確認したいのに、0が含まれていてFalseになる、といったケースです。

import pandas as pd

df = pd.DataFrame({'col1': [1, 2, 3], 'col2': [10, 0, 20]})
print(df.all())
# 期待: col2もTrueになると思っていたが、Falseになった
# col1     True
# col2    False
# dtype: bool

トラブルシューティング

  • 明確な条件付け
    全ての要素が特定の条件を満たすことを確認したい場合は、df > 0 のように明示的なブール条件を先に適用してから all() を使うことを検討してください。
    df_positive_check = df > 0
    print(df_positive_check.all())
    # col1     True
    # col2    False (0 が False になる)
    # dtype: bool
    
    これにより、「全ての数値が0より大きいか」という意図が明確になります。
  • データの確認
    まず、df.head()df.dtypesdf.describe() などを使って、DataFrame の内容とデータ型をよく確認してください。特に、数値列に0が含まれていないか、欠損値(NaN)が含まれていないかを確認します。

欠損値 (NaN) の扱いに関する誤解

問題
skipna=True (デフォルト) の場合、NaN は評価の対象外となり無視されます。これにより、NaN が存在する列や行でも、それ以外の全ての値がTrueであれば結果がTrueになることがあります。NaN も含めてFalseと評価したい場合に、この挙動が問題となることがあります。

import pandas as pd
import numpy as np

df_nan = pd.DataFrame({'A': [True, True, np.nan], 'B': [True, False, np.nan]})
print(df_nan.all()) # skipna=True がデフォルト
# 出力:
# A     True  (NaNは無視され、残りのTrueが評価される)
# B     False (Falseが含まれる)
# dtype: bool

トラブルシューティング

  • 欠損値の事前処理
    all() を呼び出す前に、fillna()dropna() などを使って欠損値を処理することを検討してください。例えば、NaN を0で埋める、特定の条件に基づいてNaN をTrue/Falseに変換するなどが考えられます。
  • skipna=False の利用
    NaN をFalseとして扱いたい場合は、skipna=False を明示的に指定します。
    print(df_nan.all(skipna=False))
    # 出力:
    # A     False (NaN が False として扱われる)
    # B     False (False が含まれる)
    # dtype: bool
    

空の DataFrame/Series

問題
空の DataFrame や Series に対して all() を呼び出すと、結果は True になります。これは「全ての要素が真である」という条件が「真でない要素が存在しない」ために満たされる、という論理に基づいています。しかし、これが期待と異なる場合があります。

import pandas as pd

empty_df = pd.DataFrame()
print(empty_df.all())
# 出力:
# Series([], dtype: bool)
# (空のSeriesが返される。axis=None の場合は True になる)

empty_series = pd.Series([])
print(empty_series.all())
# 出力: True

トラブルシューティング

  • empty 属性の確認
    all() を実行する前に、DataFrame や Series が空でないことを確認したい場合は、.empty 属性を使用します。
    if not df.empty:
        # all() の処理を行う
        pass
    else:
        print("DataFrame is empty.")
    

意図しない axis の選択

問題
axis 引数の指定を誤ると、行ごと(axis=1)に評価すべきところを列ごと(axis=0、デフォルト)に評価してしまうなど、期待と異なる結果が得られます。

import pandas as pd

df = pd.DataFrame({
    'col1': [True, True],
    'col2': [True, False]
})

# 意図せず列ごと(デフォルト)に評価した場合
print(df.all())
# col1     True
# col2    False
# dtype: bool

# 意図せず行ごとに評価した場合 (例えば、全ての行がTrueか確認したいとき)
print(df.all(axis=1))
# 0     True
# 1    False
# dtype: bool

トラブルシューティング

  • 結果の形状の確認
    all() の結果は Series またはスカラー(axis=None の場合)になるため、期待通りの形状になっているか確認します。
  • axis の明示的な指定
    混乱を避けるため、axis=0 または axis=1 を常に明示的に指定することをお勧めします。また、axis='index'axis='columns' といった文字列での指定も可能です。

all() の結果を条件式に直接使用する際の注意

問題
DataFrame.all()Series.all() の結果であるブール値の Series を Python の if 文などの条件式に直接渡すと、ValueError が発生することがあります。これは、Pandas の Series が単一の真偽値に変換できないためです(複数の真偽値を持つ可能性があるため)。

import pandas as pd

s = pd.Series([True, False])
# if s: # これを直接実行すると ValueError が発生する
#    print("Series is evaluated as True")
  • any() や all() の結果を評価
    Series 全体が単一のブール値として評価される必要がある場合は、Series に対して再度 all()any() を適用します。
    if s.all(): # 全ての要素がTrueの場合にのみTrue
        print("All elements are True")
    
    if s.any(): # 少なくとも一つの要素がTrueの場合にTrue
        print("At least one element is True")
    
    if s.empty: # Seriesが空かどうか
        print("Series is empty")
    
    ほとんどの場合、df.all().all() のように二重に all() を呼び出すことで、DataFrame全体の要素が全てTrueであるかを確認できます(ただし、これは特定のユースケースに限られます)。


DataFrame.all() メソッドは、DataFrame内の全ての要素が「真」(True)であるかどうかを効率的に確認するために使われます。ここでは、いくつかの一般的なシナリオとコード例を見ていきましょう。

例1:基本的な使い方(列ごとの評価)

最も基本的な使い方です。デフォルトでは、各列に対して操作が行われます。

import pandas as pd

# データフレームの作成
data = {
    'A': [True, True, True],
    'B': [True, False, True], # False が含まれる
    'C': [True, True, True]
}
df = pd.DataFrame(data)

print("元のDataFrame:\n", df)
# 出力:
# 元のDataFrame:
#        A      B     C
# 0   True   True  True
# 1   True  False  True
# 2   True   True  True

# 各列の全ての要素がTrueかを確認
result_col = df.all()
print("\n各列の全ての要素がTrueか (df.all()):\n", result_col)
# 出力:
# 各列の全ての要素がTrueか (df.all()):
# A     True  # 'A'列は全てTrue
# B    False  # 'B'列にはFalseが含まれる
# C     True  # 'C'列は全てTrue
# dtype: bool

# 解説:
# - 'A'列は全ての要素がTrueなので、結果はTrueになります。
# - 'B'列はFalseの要素(インデックス1)が含まれるため、結果はFalseになります。
# - 'C'列は全ての要素がTrueなので、結果はTrueになります。
# 結果はPandas Seriesとして返されます。

例2:行ごとの評価(axis=1 の使用)

axis=1 を指定することで、各行に対して全ての要素がTrueであるかを評価できます。

import pandas as pd

data = {
    'X': [True, True, False],
    'Y': [True, True, True],
    'Z': [True, False, True]
}
df = pd.DataFrame(data)

print("元のDataFrame:\n", df)
# 出力:
# 元のDataFrame:
#        X      Y      Z
# 0   True   True   True
# 1   True   True  False
# 2  False   True   True

# 各行の全ての要素がTrueかを確認
result_row = df.all(axis=1)
print("\n各行の全ての要素がTrueか (df.all(axis=1)):\n", result_row)
# 出力:
# 各行の全ての要素がTrueか (df.all(axis=1)):
# 0     True  # 0行目 (True, True, True) は全てTrue
# 1    False  # 1行目 (True, True, False) はFalseを含む
# 2    False  # 2行目 (False, True, True) はFalseを含む
# dtype: bool

# 解説:
# - 0行目は全ての要素がTrueなので、結果はTrueになります。
# - 1行目と2行目にはFalseの要素が含まれるため、結果はFalseになります。
# 結果はPandas Seriesとして返されます。

例3:数値データでの使用(0はFalse、非ゼロはTrue)

all() はブール値だけでなく、数値データに対しても機能します。この場合、0False として扱われ、それ以外の非ゼロの数値は True として扱われます。

import pandas as pd

data = {
    '値1': [1, 2, 3],
    '値2': [4, 0, 5],  # 0 が含まれる
    '値3': [6, 7, 8]
}
df_num = pd.DataFrame(data)

print("元の数値DataFrame:\n", df_num)
# 出力:
# 元の数値DataFrame:
#    値1  値2  値3
# 0   1   4   6
# 1   2   0   7
# 2   3   5   8

# 各列の全ての要素が非ゼロかを確認
result_num = df_num.all()
print("\n各列の全ての要素が非ゼロか (df_num.all()):\n", result_num)
# 出力:
# 各列の全ての要素が非ゼロか (df_num.all()):
# 値1     True
# 値2    False # 0 が含まれるため
# 値3     True
# dtype: bool

# 解説:
# - '値1' と '値3' 列は全て非ゼロなのでTrue。
# - '値2' 列には0が含まれるためFalse。

例4:欠損値(NaN)の扱い (skipna 引数)

デフォルトでは skipna=True であり、NaNは無視されます。skipna=False に設定すると、NaNはFalseとして扱われます。

import pandas as pd
import numpy as np

data = {
    'データA': [True, True, np.nan], # NaN を含む
    'データB': [True, False, True]
}
df_nan = pd.DataFrame(data)

print("元のNaNを含むDataFrame:\n", df_nan)
# 出力:
# 元のNaNを含むDataFrame:
#    データA  データB
# 0   True   True
# 1   True  False
# 2    NaN   True

# skipna=True (デフォルト) の場合
result_skipna_true = df_nan.all(skipna=True)
print("\nNaNを無視して評価 (df_nan.all(skipna=True)):\n", result_skipna_true)
# 出力:
# NaNを無視して評価 (df_nan.all(skipna=True)):
# データA     True # NaNは無視されるので、残りのTrueが評価される
# データB    False # Falseが含まれる
# dtype: bool

# skipna=False の場合
result_skipna_false = df_nan.all(skipna=False)
print("\nNaNをFalseとして評価 (df_nan.all(skipna=False)):\n", result_skipna_false)
# 出力:
# NaNをFalseとして評価 (df_nan.all(skipna=False)):
# データA    False # NaN が False として扱われるため
# データB    False # False が含まれるため
# dtype: bool

# 解説:
# - skipna=True の場合、'データA'列のNaNは無視され、残りのTrueによって結果はTrue。
# - skipna=False の場合、'データA'列のNaNがFalseとして扱われるため、結果はFalse。

例5:DataFrame全体の全ての要素がTrueかを確認

DataFrame全体の全ての要素がTrueであることを確認したい場合は、df.all().all() のように二重に all() を呼び出すことができます。

import pandas as pd

df1 = pd.DataFrame({'C1': [True, True], 'C2': [True, True]})
df2 = pd.DataFrame({'C1': [True, False], 'C2': [True, True]})

print("df1:\n", df1)
print("df2:\n", df2)

# df1 の全ての要素がTrueか
all_true_df1 = df1.all().all()
print("\ndf1の全ての要素がTrueか:", all_true_df1) # True
# 解説:
# df1.all() は Series([True, True]) を返し、その Series の .all() も True になる。

# df2 の全ての要素がTrueか
all_true_df2 = df2.all().all()
print("df2の全ての要素がTrueか:", all_true_df2) # False
# 解説:
# df2.all() は Series([False, True]) を返し、その Series の .all() は False になる。

例6:条件に基づいたフィルタリングでの応用

all() は、特定の条件を満たす行や列をフィルタリングする際によく使われます。

import pandas as pd

df = pd.DataFrame({
    '商品A': [100, 120, 90],
    '商品B': [50, 60, 40],
    '商品C': [150, 180, 100]
})
print("元のDataFrame:\n", df)

# 全ての商品が100円以上の行を見つける
# まずブール値のDataFrameを作成
df_over_100 = df >= 100
print("\n100以上のブールDataFrame:\n", df_over_100)
# 出力:
# 100以上のブールDataFrame:
#    商品A  商品B  商品C
# 0   True  False   True
# 1   True  False   True
# 2  False  False   True

# 次に、各行で全ての要素がTrueかを確認
rows_all_over_100 = df_over_100.all(axis=1)
print("\n全ての要素が100以上の行 (ブールSeries):\n", rows_all_over_100)
# 出力:
# 全ての要素が100以上の行 (ブールSeries):
# 0    False # 商品BがFalse
# 1    False # 商品BがFalse
# 2    False # 商品A, 商品BがFalse
# dtype: bool

# フィルタリング
filtered_df = df[rows_all_over_100]
print("\nフィルタリングされたDataFrame (全ての要素が100以上の行):\n", filtered_df)
# 出力:
# フィルタリングされたDataFrame (全ての要素が100以上の行):
# Empty DataFrame
# Columns: [商品A, 商品B, 商品C]
# Index: []

# この例では該当する行がなかったので空のDataFrameが返されました。
# 例えば、全ての価格を100以上にしてみると...
df_new = pd.DataFrame({
    '商品A': [100, 120, 150],
    '商品B': [100, 110, 130],
    '商品C': [150, 180, 100]
})

df_over_100_new = df_new >= 100
rows_all_over_100_new = df_over_100_new.all(axis=1)
filtered_df_new = df_new[rows_all_over_100_new]
print("\n更新されたDataFrame:\n", df_new)
print("\n更新されたフィルタリング結果:\n", filtered_df_new)
# 出力:
# 更新されたフィルタリング結果:
#    商品A  商品B  商品C
# 0  100  100  150
# 1  120  110  180
# 2  150  130  100


pandas.DataFrame.all はDataFrame内の全ての要素が真であるかを効率的にチェックする便利なメソッドですが、同じような結果を得るために、異なるアプローチやより詳細な制御が必要な場合があります。ここでは、いくつかの代替方法と、それぞれのユースケースについて説明します。

各列/行のブール Series を直接確認する

df.all() の結果はブール値の Series です。この Series を個別に確認することで、all() と同じようなロジックを組み立てることができます。