pandas.DataFrame.empty

2025-05-26

具体的には以下のようになります。

  • False を返す場合

    • DataFrameに一つでもデータ(要素)が存在する場合。
    • たとえDataFrame内のすべての要素が NaN (Not a Number) であっても、データが存在するとみなされるため、emptyFalse を返します。すべての要素が NaN のDataFrameが本当に「空」であると見なしたい場合は、dropna() メソッドで NaN を削除してから empty を確認する必要があります。
    • DataFrameにデータがまったく含まれていない場合(行も列もゼロの場合)。
    • 列は定義されているが、行が一つもない場合。
    • 行は定義されているが、列が一つもない場合。

使用例

import pandas as pd
import numpy as np

# 1. 空のDataFrame
df_empty = pd.DataFrame()
print("空のDataFrame:")
print(df_empty)
print(f"df_empty.empty: {df_empty.empty}") # True を返す
print("-" * 30)

# 2. 列は定義されているが、行がないDataFrame
df_cols_only = pd.DataFrame(columns=['A', 'B', 'C'])
print("列は定義されているが、行がないDataFrame:")
print(df_cols_only)
print(f"df_cols_only.empty: {df_cols_only.empty}") # True を返す
print("-" * 30)

# 3. データが含まれるDataFrame
df_full = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
print("データが含まれるDataFrame:")
print(df_full)
print(f"df_full.empty: {df_full.empty}") # False を返す
print("-" * 30)

# 4. 全てNaNのDataFrame
df_nan = pd.DataFrame({'A': [np.nan], 'B': [np.nan]})
print("全てNaNのDataFrame:")
print(df_nan)
print(f"df_nan.empty: {df_nan.empty}") # False を返す(NaNもデータとみなされるため)
print("-" * 30)

# 5. 全てNaNのDataFrameからNaNを削除した場合
df_nan_dropped = df_nan.dropna()
print("全てNaNのDataFrameからNaNを削除した場合:")
print(df_nan_dropped)
print(f"df_nan_dropped.empty: {df_nan_dropped.empty}") # True を返す
print("-" * 30)

Pythonでは、空のリスト([])や辞書({})などは bool() で評価すると False となります。しかし、PandasのDataFrameでは、パフォーマンスや意図の明確化のため、bool(DataFrame)ValueError を発生させます。

DataFrameが空であるかどうかをチェックする場合は、必ず df.empty 属性を使用する必要があります。

df_empty = pd.DataFrame()
# if df_empty: # これはエラーになる
#     print("Empty!")
if df_empty.empty:
    print("DataFrameは空です。")


bool(df) を使って空判定しようとする

エラーの状況
Pythonのリストや辞書のように、DataFrameを直接 if df: のようにブール値として評価しようとすると、ValueError が発生します。

import pandas as pd

df = pd.DataFrame()
# if df: # これを実行すると ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
#     print("DataFrame is not empty")

理由
Pandas DataFrameは、単一の明確な真偽値を持つようには設計されていません。複数の要素が含まれるため、例えば「すべての要素がTrueならTrue」なのか、「一つでもTrueがあればTrue」なのかなど、その評価が曖昧になるためです。このため、Pandasは明示的な empty 属性の使用を強制します。

トラブルシューティング
常に df.empty を使用してDataFrameが空かどうかをチェックしてください。

df = pd.DataFrame()
if df.empty:
    print("DataFrameは空です。")
else:
    print("DataFrameは空ではありません。")

NaN (Not a Number) のみが含まれるDataFrameを「空」と誤解する

エラーの状況
DataFrameにデータは入っているものの、そのすべてが NaN である場合に、df.emptyFalse を返すため、「空ではない」と判断され、期待する処理が行われないことがあります。

import pandas as pd
import numpy as np

df_nan = pd.DataFrame({'A': [np.nan], 'B': [np.nan]})
print(df_nan)
print(f"df_nan.empty: {df_nan.empty}") # False
# df_nan.empty が True を返すことを期待していたが、実際は False

理由
NaN はPandasにおいて「欠損値」であり、「データが存在しない」こととは異なります。DataFrameのサイズ(行数と列数)がゼロでない限り、empty 属性は False を返します。

トラブルシューティング
DataFrameからすべての NaN 値を削除した後で空かどうかをチェックすることで、意図した通りの「実質的に空」であるかを判定できます。

df_nan = pd.DataFrame({'A': [np.nan], 'B': [np.nan]})
df_nan_dropped = df_nan.dropna(how='all') # 全てのNaNの行を削除
if df_nan_dropped.empty:
    print("NaNのみの行を削除すると、DataFrameは空になります。")
else:
    print("NaNのみの行を削除しても、DataFrameは空ではありません。")

# または、特定の列に有効な値があるかどうかをチェックする
if df_nan['A'].dropna().empty and df_nan['B'].dropna().empty:
    print("すべての列がNaNのみで構成されています。")

条件によってDataFrameが空になる可能性がある処理の後のハンドリング不足

エラーの状況
フィルタリング、結合 (merge/join)、グループ化 (groupby) などの操作を行った結果、DataFrameが空になる可能性があるにもかかわらず、その後の処理で空のDataFrameを前提としないコードを書いてしまうと、KeyErrorAttributeError などが発生することがあります。

import pandas as pd

df = pd.DataFrame({'A': [1, 2, 3], 'B': ['x', 'y', 'z']})

# 存在しない条件でフィルタリング
filtered_df = df[df['A'] > 100]
print(f"filtered_df:\n{filtered_df}")
print(f"filtered_df.empty: {filtered_df.empty}") # True

# 空のDataFrameに対して列にアクセスしようとする(一般的なエラー)
# print(filtered_df['B'].iloc[0]) # IndexError: single positional indexer is out-of-bounds
# print(filtered_df.loc[0, 'B']) # KeyError: 0

理由
DataFrameが空の場合、行も列も存在しないため、インデックスや列名を使って要素にアクセスしようとするとエラーになります。

トラブルシューティング
DataFrameに対して何らかの操作を行う前に、または操作後に、empty 属性を使ってDataFrameが空でないことを確認してから、その後の処理に進むようにします。

df = pd.DataFrame({'A': [1, 2, 3], 'B': ['x', 'y', 'z']})

filtered_df = df[df['A'] > 100]

if not filtered_df.empty:
    print("フィルタリングされたDataFrameにデータがあります:")
    print(filtered_df)
    # ここにデータがある場合の処理
else:
    print("フィルタリングされたDataFrameは空です。")
    # ここにデータがない場合の処理 (例: ログ出力、代替処理)

# 関数内でDataFrameを返す場合も同様
def process_data(df_input):
    processed_df = df_input[df_input['value'] > 10]
    if processed_df.empty:
        print("処理結果のDataFrameは空です。")
        return None # または空のDataFrameを返す
    else:
        print("処理結果のDataFrame:")
        print(processed_df)
        return processed_df

df_test = pd.DataFrame({'value': [5, 8, 12]})
result_df = process_data(df_test)
if result_df is not None:
    # result_df を使った処理
    pass

df_empty_test = pd.DataFrame({'value': [1, 2, 3]})
result_empty_df = process_data(df_empty_test)

エラーの状況
pd.read_csv()pd.read_excel() などで、ファイル自体が空、またはヘッダー行しかない場合、pandas.errors.EmptyDataError が発生することがあります。このエラーは df.empty をチェックする前に発生します。

# 仮の空ファイルを作成
with open("empty_file.csv", "w") as f:
    f.write("") # またはヘッダーのみ: f.write("col1,col2\n")

try:
    df_from_file = pd.read_csv("empty_file.csv")
    print(f"df_from_file.empty: {df_from_file.empty}")
except pd.errors.EmptyDataError as e:
    print(f"ファイルが空のためエラーが発生しました: {e}")

理由
EmptyDataError は、Pandasがデータを読み込もうとしたが、読み込むべきデータが見つからなかった場合に発生する例外です。これは、DataFrame.empty が評価されるよりも前の、データの読み込みフェーズで起こります。

トラブルシューティング
ファイルからデータを読み込む際には、try-except ブロックを使用して pandas.errors.EmptyDataError を捕捉し、適切にハンドリングします。

import pandas as pd
import numpy as np
import os

file_path = "data.csv"

# テスト用のファイルを作成 (データあり)
with open(file_path, "w") as f:
    f.write("col1,col2\n1,A\n2,B\n")

try:
    df = pd.read_csv(file_path)
    if df.empty:
        print(f"ファイル '{file_path}' から読み込んだDataFrameは空です。")
    else:
        print(f"ファイル '{file_path}' からデータを読み込みました:")
        print(df)
except pd.errors.EmptyDataError:
    print(f"ファイル '{file_path}' は空か、またはヘッダーのみです。")
except FileNotFoundError:
    print(f"ファイル '{file_path}' が見つかりません。")
except Exception as e:
    print(f"データの読み込み中に予期せぬエラーが発生しました: {e}")
finally:
    # テスト用ファイルの削除
    if os.path.exists(file_path):
        os.remove(file_path)

# テスト用のファイルを作成 (空)
file_path_empty = "empty_data.csv"
with open(file_path_empty, "w") as f:
    pass # 空ファイル

try:
    df_empty_file = pd.read_csv(file_path_empty)
    if df_empty_file.empty:
        print(f"ファイル '{file_path_empty}' から読み込んだDataFrameは空です。")
    else:
        print(f"ファイル '{file_path_empty}' からデータを読み込みました:")
        print(df_empty_file)
except pd.errors.EmptyDataError:
    print(f"ファイル '{file_path_empty}' は空か、またはヘッダーのみです。")
except FileNotFoundError:
    print(f"ファイル '{file_path_file}' が見つかりません。")
except Exception as e:
    print(f"データの読み込み中に予期せぬエラーが発生しました: {e}")
finally:
    # テスト用ファイルの削除
    if os.path.exists(file_path_empty):
        os.remove(file_path_empty)


pandas.DataFrame.empty のプログラミング例

pandas.DataFrame.empty は、DataFrameがデータを含んでいるかどうかを効率的にチェックするための重要な属性です。ここでは、一般的なシナリオにおける使用例をいくつか紹介します。

import pandas as pd
import numpy as np

print("--- 1. 基本的な空のDataFrameのチェック ---")
# 完全な空のDataFrame
df_empty_full = pd.DataFrame()
print(f"df_empty_full:\n{df_empty_full}")
print(f"df_empty_full.empty: {df_empty_full.empty}") # True

print("\n--- 2. 列のみ定義され、行がないDataFrameのチェック ---")
# 列は定義されているが、行がないDataFrame
df_cols_only = pd.DataFrame(columns=['A', 'B', 'C'])
print(f"df_cols_only:\n{df_cols_only}")
print(f"df_cols_only.empty: {df_cols_only.empty}") # True

print("\n--- 3. データを含むDataFrameのチェック ---")
# データを含むDataFrame
df_data = pd.DataFrame({'col1': [1, 2], 'col2': ['X', 'Y']})
print(f"df_data:\n{df_data}")
print(f"df_data.empty: {df_data.empty}") # False

print("\n--- 4. すべてNaNのDataFrameのチェック ---")
# 全ての要素がNaNのDataFrame
df_all_nan = pd.DataFrame({'col1': [np.nan], 'col2': [np.nan]})
print(f"df_all_nan:\n{df_all_nan}")
print(f"df_all_nan.empty: {df_all_nan.empty}") # False (NaNもデータとみなされるため)

# NaNのみのDataFrameを実質的に空と判断したい場合
df_all_nan_dropped = df_all_nan.dropna(how='all')
print(f"\ndf_all_nan.dropna(how='all'):\n{df_all_nan_dropped}")
print(f"df_all_nan_dropped.empty: {df_all_nan_dropped.empty}") # True

例1: 関数の引数として渡されたDataFrameが空でないか確認する

関数がDataFrameを受け取り、そのDataFrameが空でない場合にのみ特定の処理を実行したい場合によく使われます。

def process_dataframe(df: pd.DataFrame):
    """
    DataFrameを受け取り、空でない場合にのみ処理を実行する関数。
    """
    if df.empty:
        print("警告: 処理するDataFrameが空です。")
        return None # または空のDataFrameを返す、エラーを発生させるなど

    print("DataFrameを処理中...")
    # 例: 特定の列を合計する
    if 'value' in df.columns:
        total = df['value'].sum()
        print(f"合計値: {total}")
        return total
    else:
        print("エラー: 'value' 列が見つかりません。")
        return None

print("\n--- 5. 関数内での空チェック ---")
df1 = pd.DataFrame({'value': [10, 20, 30], 'category': ['A', 'B', 'A']})
process_dataframe(df1)

df2 = pd.DataFrame() # 空のDataFrame
process_dataframe(df2)

df3 = pd.DataFrame(columns=['id', 'name']) # 列のみのDataFrame
process_dataframe(df3)

df4 = pd.DataFrame({'other_col': [1, 2]}) # 'value' 列がないDataFrame
process_dataframe(df4)

例2: フィルタリングや結合操作の結果が空になる可能性がある場合

データの前処理や分析において、特定の条件でフィルタリングしたり、複数のDataFrameを結合したりした結果、DataFrameが空になることがあります。その後の処理でエラーを防ぐために empty を使用します。

print("\n--- 6. フィルタリング後の空チェック ---")
data = {'product': ['A', 'B', 'C', 'D'], 'price': [100, 200, 150, 50]}
df_products = pd.DataFrame(data)

# 条件に合うデータがある場合
expensive_products = df_products[df_products['price'] > 120]
if not expensive_products.empty:
    print("高価な商品:")
    print(expensive_products)
else:
    print("高価な商品は見つかりませんでした。")

# 条件に合うデータがない場合
very_expensive_products = df_products[df_products['price'] > 500]
if not very_expensive_products.empty:
    print("非常に高価な商品:")
    print(very_expensive_products)
else:
    print("非常に高価な商品は見つかりませんでした。")

print("\n--- 7. 結合(merge)後の空チェック ---")
df_left = pd.DataFrame({'id': [1, 2, 3], 'name': ['Alice', 'Bob', 'Charlie']})
df_right = pd.DataFrame({'id': [2, 4], 'score': [85, 90]})

# 共通のIDがある結合
merged_df = pd.merge(df_left, df_right, on='id', how='inner')
if not merged_df.empty:
    print("結合結果 (データあり):")
    print(merged_df)
else:
    print("結合結果は空でした。")

# 共通のIDがない結合
df_right_no_match = pd.DataFrame({'id': [5, 6], 'score': [70, 75]})
merged_no_match_df = pd.merge(df_left, df_right_no_match, on='id', how='inner')
if not merged_no_match_df.empty:
    print("結合結果 (データなし、表示されないはず):")
    print(merged_no_match_df)
else:
    print("結合結果は空でした。")

例3: 外部データソースからの読み込み後

pd.read_csv などでファイルを読み込む際、ファイルが空だったり、ヘッダー行しか含まれていなかったりする場合があります。この場合、EmptyDataError が発生するか、空のDataFrameが返される可能性があります。

import os

print("\n--- 8. ファイル読み込み後の空チェックとエラーハンドリング ---")
file_name_data = "temp_data_with_content.csv"
file_name_empty = "temp_empty_file.csv"
file_name_header_only = "temp_header_only.csv"

# テストファイルの作成
with open(file_name_data, 'w') as f:
    f.write("A,B\n1,X\n2,Y\n")
with open(file_name_empty, 'w') as f:
    pass # 空のファイル
with open(file_name_header_only, 'w') as f:
    f.write("C,D\n")

def load_and_check(file_path):
    print(f"\nファイル '{file_path}' を読み込み中...")
    try:
        df = pd.read_csv(file_path)
        if df.empty:
            print(f"DataFrameは空です。")
        else:
            print("DataFrameが読み込まれました:")
            print(df)
    except pd.errors.EmptyDataError:
        print(f"エラー: ファイル '{file_path}' はデータを含んでいません(ヘッダーのみの場合も含む)。")
    except FileNotFoundError:
        print(f"エラー: ファイル '{file_path}' が見つかりません。")
    except Exception as e:
        print(f"予期せぬエラーが発生しました: {e}")

load_and_check(file_name_data)
load_and_check(file_name_empty)
load_and_check(file_name_header_only) # ヘッダーのみの場合、通常はempty=Trueになる

# テストファイルのクリーンアップ
os.remove(file_name_data)
os.remove(file_name_empty)
os.remove(file_name_header_only)


    • 意味
      DataFrameの行数が0であるかどうかをチェックします。これは df.empty と同じ結果を返すことがほとんどですが、厳密には df.empty が列が定義されていても行がなければ True を返すのに対し、len(df) は行数を見るため、ほとんどの場合同じです。
    • 利点
      Pythonの一般的なオブジェクト(リストなど)の長さをチェックする方法と似ており、直感的に理解しやすい。
    • 欠点
      df.empty の方がPandasのDataFrameに特化しており、意図が明確です。また、len(df) は内部的に df.__len__ を呼び出すため、df.empty よりもわずかにオーバーヘッドがある可能性があります(通常は無視できるレベル)。
    • コード例
      import pandas as pd
      
      df_empty = pd.DataFrame()
      df_data = pd.DataFrame({'A': [1, 2]})
      df_cols_only = pd.DataFrame(columns=['X', 'Y'])
      
      print(f"df_empty.empty: {df_empty.empty}, len(df_empty): {len(df_empty)}") # True, 0
      print(f"df_data.empty: {df_data.empty}, len(df_data): {len(df_data)}")     # False, 2
      print(f"df_cols_only.empty: {df_cols_only.empty}, len(df_cols_only): {len(df_cols_only)}") # True, 0
      
  1. df.dropna(how='all').empty (すべてのNaNの行を削除後に空であるかどうかのチェック)

    • 意味
      DataFrameからすべての値がNaNである行を削除した結果、DataFrameが空になるかどうかをチェックします。これは、データが実質的に存在しない(つまり、残っている行には有効なデータがない)状態を「空」と見なしたい場合に非常に便利です。
    • 利点
      実際に意味のあるデータがDataFrame内に存在するかどうかを判断するのに役立ちます。
    • 欠点
      DataFrameのコピーを作成し、dropna() 操作を実行するため、計算コストがかかります。元のDataFrameは変更されません。
    • コード例
      import pandas as pd
      import numpy as np
      
      df_empty = pd.DataFrame()
      df_data = pd.DataFrame({'A': [1, 2]})
      df_all_nan_rows = pd.DataFrame({'A': [np.nan, np.nan], 'B': [np.nan, np.nan]})
      df_mixed_nan = pd.DataFrame({'A': [1, np.nan], 'B': [np.nan, 2]})
      df_some_nan_rows = pd.DataFrame({'A': [np.nan, 1], 'B': [np.nan, 2]})
      df_row_all_nan = pd.DataFrame({'A': [1, np.nan], 'B': [2, np.nan]})
      
      
      print(f"df_empty.dropna(how='all').empty: {df_empty.dropna(how='all').empty}") # True
      print(f"df_data.dropna(how='all').empty: {df_data.dropna(how='all').empty}") # False
      print(f"df_all_nan_rows.dropna(how='all').empty: {df_all_nan_rows.dropna(how='all').empty}") # True
      print(f"df_mixed_nan.dropna(how='all').empty: {df_mixed_nan.dropna(how='all').empty}") # False (有効なデータを持つ行があるため)
      print(f"df_some_nan_rows.dropna(how='all').empty: {df_some_nan_rows.dropna(how='all').empty}") # False
      print(f"df_row_all_nan.dropna(how='all').empty: {df_row_all_nan.dropna(how='all').empty}") # False
      
      df_row_all_nan の例では、dropna(how='all') を適用すると2行目が削除されますが、1行目は残るため emptyFalse になります。
  2. df.size == 0 (要素の総数によるチェック)

    • 意味
      DataFrame内の要素の総数(行数 × 列数)が0であるかどうかをチェックします。これは df.empty と同じ結果を返します。
    • 利点
      empty 属性の内部的な実装に近い考え方であり、明示的に要素数を確認できます。
    • 欠点
      df.empty がより直接的でPandasの慣習に沿っています。
    • コード例
      import pandas as pd
      
      df_empty = pd.DataFrame()
      df_data = pd.DataFrame({'A': [1, 2]})
      df_cols_only = pd.DataFrame(columns=['X', 'Y'])
      
      print(f"df_empty.empty: {df_empty.empty}, df_empty.size == 0: {df_empty.size == 0}") # True, True
      print(f"df_data.empty: {df_data.empty}, df_data.size == 0: {df_data.size == 0}")     # False, False
      print(f"df_cols_only.empty: {df_cols_only.empty}, df_cols_only.size == 0: {df_cols_only.size == 0}") # True, True
      
代替方法意味合いdf.empty との比較ユースケース
len(df) または df.shape[0]行数がゼロかほとんどの場合 df.empty と同じ結果。df.empty の方が推奨。Pythonの他のコレクションと同じように長さをチェックしたい場合。
df.isnull().all().all()すべての要素がNaNかdf.empty とは異なる概念。NaNのDataFrameは empty=False だがこれは Trueデータは存在するが行っているが、有効なデータが一切ないかを判断したい場合。
df.dropna(how='all').emptyすべてNaNの行を削除した後で空になるか実質的なデータ有無のチェック。df.empty より深い意味での「空」。実質的なデータがない状態(NaNのみの行は無視したい)を「空」と見なしたい場合。
df.size == 0要素の総数がゼロかdf.empty と同じ結果。df.empty の方が推奨。明示的に要素数をチェックしたい場合。

最も推奨されるのは、ほとんどのシナリオで df.empty を使用することです。 これはPandasが提供する最も意図が明確で効率的な方法だからです。