ValueError: The truth value of an array … is ambiguous の原因と直し方(NumPy・pandas)

「ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()」は、複数の値が入ったNumPy配列やpandasのSeriesを、if文やand・orで「1つのTrue/False」として扱おうとしたときに出るエラーです。「1つでも満たすか」なら.any()、「すべて満たすか」なら.all()、条件の組み合わせなら&・|に括弧を付ける、と書き分ければ解消します。

この記事では、エラーが出るコードを実際に動かし、出たメッセージをそのまま載せたうえで、原因のパターンごとに直し方を説明します。動作確認の環境は Python 3.12.15、NumPy 2.5.4、pandas 3.0.6 です(2026年10月14日確認)。

エラーメッセージは3種類ある

同じ原因でも、どのオブジェクトを真偽値にしようとしたかで文面が少し変わります。今回の環境で実際に出たメッセージは次のとおりです。

何を真偽値にしたか 出たメッセージ
要素が2つ以上のNumPy配列 ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
pandasのSeries ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
pandasのDataFrame ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
要素が0個のNumPy配列 ValueError: The truth value of an empty array is ambiguous. Use `array.size > 0` to check that an array is not empty.
pandasの欠損値 pd.NA TypeError: boolean value of NA is ambiguous

なお、要素がちょうど1つのNumPy配列(例:np.array([3]) > 2)はエラーにならず、そのまま True と評価されました。「テストデータでは動いたのに本番データで落ちた」というときは、データの件数が1件から複数件に増えたことが原因のことがあります。

なぜ「ambiguous(あいまい)」なのか

NumPy配列やSeriesに > や == を使うと、結果は1つの True/False ではなく、要素ごとの真偽値が並んだ配列になります。

import numpy as np

arr = np.array([1, 6, 3])
print(arr > 5)

if arr > 5:
    print("5より大きい")

実行結果:

[False  True False]
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    if arr > 5:
       ^^^^^^^
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

[False True False] を if文に渡されても、Pythonには「1つでもTrueがあるから真」なのか「Falseが混じっているから偽」なのか判断できません。そこでNumPyは推測せずにエラーを出します。pandasの公式ドキュメントでも、Seriesをif文に入れたときに「長さが0でないから真」なのか「Falseを含むから偽」なのかが不明確なため、ValueErrorを出すと説明されています(pandas: Frequently Asked Questions (FAQ))。

この「配列を1つの真偽値に変換する」処理は、if文だけでなく次の場面でも起こります。

  • if / while の条件
  • and、or、not
  • assert a == b
  • 組み込みの max()・min() に配列と数値を渡したとき
  • 自作関数の中の if文に、うっかりSeriesを丸ごと渡したとき

以下、パターンごとに直し方を見ていきます。

対処法1:「1つでも」なら any()、「すべて」なら all()

エラーメッセージが勧めている方法です。比較の結果に .any() を付けると「1つでもTrueがあるか」、.all() を付けると「すべてTrueか」という1つの真偽値になります(NumPy: ndarray.any)。

import numpy as np
import pandas as pd

arr = np.array([1, 6, 3])
print((arr > 5).any())   # 1つでも5より大きいか
print((arr > 5).all())   # すべて5より大きいか
print((arr > 0).all())

s = pd.Series([10, 20, 5])
if (s > 15).any():
    print("15を超える値があります")
if not (s > 0).all():
    print("0以下の値があります")
else:
    print("すべて正の値です")

実行結果:

True
False
True
15を超える値があります
すべて正の値です

大事なのは、.any() と .all() のどちらにするかは「あなたが何を判定したいか」で決まる、という点です。エラーを消すためだけにどちらかを付けると、エラーは消えても判定の意味が変わってしまいます。たとえば「全員が80点以上なら合格」なのに .any() を使うと、1人でも80点以上なら合格扱いになります。

DataFrameでは行ごと・列ごとにも判定できる

DataFrameに .any() を付けると、まず列ごとの結果(Series)が返ります。axis=1 を指定すると行ごとになります。DataFrame全体で1つの真偽値にしたいときは、.any() を2回重ねるか、NumPy配列に変換してから .any() を呼びます。

import pandas as pd

df = pd.DataFrame({"A": [10, 20, None], "B": [5, 15, 25]})
print(df.isna())
print(df.isna().any())          # 列ごと
print(df.isna().any(axis=1))    # 行ごと
print(df.isna().any().any())    # 全体で1つでもあるか
print(df.isna().to_numpy().any())

実行結果:

       A      B
0  False  False
1  False  False
2   True  False
A     True
B    False
dtype: bool
0    False
1    False
2     True
dtype: bool
True
True

if df.isna().any(): と1回だけ付けた場合、結果はまだSeriesなので、同じエラーがもう一度出ます。DataFrameのときは「何回 any() を付けたら1つの値になるか」を意識してください。

対処法2:and・or・not ではなく &・|・~ を使う

pandasで「70点以上かつ90点未満」のように条件を組み合わせて行を絞り込むとき、Pythonの and を使うとエラーになります。and は左右をそれぞれ1つの真偽値に変換しようとするためです。

import pandas as pd

df = pd.DataFrame({"name": ["A", "B", "C", "D"], "score": [72, 88, 95, 60]})
print(df[(df["score"] >= 70) and (df["score"] < 90)])

実行結果:

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    print(df[(df["score"] >= 70) and (df["score"] < 90)])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  (pandas内部の行は省略)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

要素ごとに条件を組み合わせるには、and の代わりに &、or の代わりに |、not の代わりに ~ を使います。pandasの公式ドキュメントでも、この3つを使い、各条件を括弧で囲むよう説明されています(pandas: Indexing and selecting data)。

import pandas as pd

df = pd.DataFrame({"name": ["A", "B", "C", "D"], "score": [72, 88, 95, 60]})
print(df[(df["score"] >= 70) & (df["score"] < 90)])
print(df[(df["score"] < 65) | (df["score"] > 90)])
print(df[~(df["score"] >= 80)])

実行結果:

  name  score
0    A     72
1    B     88
  name  score
2    C     95
3    D     60
  name  score
0    A     72
3    D     60

括弧を忘れても同じエラーになる

& を使っていても、括弧を省くと同じエラーが出ます。

print(df[df["score"] >= 70 & df["score"] < 90])
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Pythonでは & のほうが >= や < よりも先に計算されるため、上の式は df["score"] >= (70 & df["score"]) < 90 と解釈されます。さらに a >= b < c はPythonの連鎖比較として (a >= b) and (b < c) に展開されるので、結局 and を使ったのと同じ状態になります。条件は1つずつ必ず括弧で囲む、と覚えておけば避けられます。

括弧が多くて読みにくいときは、df.query("score >= 70 and score < 90") のように文字列で書く query() を使う方法もあります。query() の文字列の中では and・or が使えます。

対処法3:「空かどうか」は .empty や size で調べる

Pythonのリストなら if lst: で「空でないか」を判定できますが、DataFrameやSeriesでは同じ書き方がエラーになります。空のSeriesでも、今回の環境では The truth value of a Series is ambiguous が出ました。pandasでは .empty を使います(pandas: DataFrame.empty)。

import numpy as np
import pandas as pd

df = pd.DataFrame({"score": [72, 88, 95]})
empty = df[df["score"] > 100]
print(empty.empty)        # 空ならTrue
print(len(empty) == 0)
if empty.empty:
    print("該当なし")

arr = np.array([])
print(arr.size > 0)

実行結果:

True
True
該当なし
False

NumPyの空配列を if arr: に入れると、ValueError: The truth value of an empty array is ambiguous. Use `array.size > 0` to check that an array is not empty. と、メッセージの中で直し方まで示してくれます。

なお、.empty はNaNだけの列でも「空ではない」と判定します。「中身が全部欠損かどうか」を知りたいなら df.dropna().empty や df.isna().all().all() のように、目的に合わせて書き分けてください。

対処法4:1件だけ取り出したいなら .item()

IDで1行を絞り込み、その値で分岐したい、という場面もよくあります。絞り込んだ結果は1件でもSeriesのままなので、.item() で中身の値を取り出します(pandas: Series.item)。

import pandas as pd

df = pd.DataFrame({"id": [101, 102, 103], "score": [72, 88, 95]})
row = df.loc[df["id"] == 102, "score"]
print(row)
print(row.item())
if row.item() >= 80:
    print("合格")

実行結果:

1    88
Name: score, dtype: int64
88
合格

.item() は要素がちょうど1つのときだけ使えます。同じIDが2行あると、次のエラーになります。

ValueError: can only convert an array of size 1 to a Python scalar

このエラーが出たら、データに重複があるサインです。「必ず1件」という前提が正しいかを先に確かめてください。NumPy配列にも同じ名前のメソッドがあります(NumPy: ndarray.item)。

a.bool() はpandas 3.0で削除済み

Series・DataFrameのエラーメッセージには今も a.bool() が候補として出てきますが、Series.bool と DataFrame.bool はpandas 3.0で削除されています(What’s new in 3.0.0、2026年10月14日確認)。実際にpandas 3.0.6の pd.Series に bool 属性があるか調べると False でした。古い記事の s.bool() をまねると AttributeError になるので、1件の値を取り出すなら .item() を使ってください。

対処法5:要素ごとに分岐したいなら np.where や apply

「80点以上なら合格、それ以外は不合格」という列を作りたいとき、if文を使った関数にSeriesを丸ごと渡すとエラーになります。

import pandas as pd

df = pd.DataFrame({"score": [72, 88, 95, 60]})

def judge(x):
    if x >= 80:
        return "合格"
    return "不合格"

print(judge(df["score"]))   # ValueError: The truth value of a Series is ambiguous. ...

この場合、本当にやりたいのは「1つの真偽値で分岐する」ことではなく「要素ごとに違う値を入れる」ことです。np.where(条件, 真のときの値, 偽のときの値) を使うと、if文を書かずに要素ごとの結果が得られます(NumPy: numpy.where)。

import numpy as np
import pandas as pd

arr = np.array([1, 6, 3])
print(np.where(arr > 5, "大", "小"))

df = pd.DataFrame({"score": [72, 88, 95, 60]})
df["result"] = np.where(df["score"] >= 80, "合格", "不合格")
print(df)

実行結果:

['小' '大' '小']
   score result
0     72    不合格
1     88     合格
2     95     合格
3     60    不合格

if文の関数をそのまま使いたい場合は、df["score"].apply(judge) とすれば1要素ずつ関数に渡されるので、エラーにはなりません。ただし行数が多いと np.where より遅くなります。

見落としやすいその他のパターン

assert a == b で配列を比べている

テストコードで assert a == b と書くと、a == b が要素ごとの配列になるため同じエラーが出ます。配列全体が等しいかを調べるなら np.array_equal(a, b) か (a == b).all() を使います。pandasなら df1.equals(df2) が使えます。

import numpy as np

a = np.array([1, 2, 3])
b = np.array([1, 2, 3])
print(np.array_equal(a, b))
print((a == b).all())
True
True

== None で配列かどうかを判定している

変数がNoneかどうかを if data == None: と書くと、data が配列だったときに要素ごとの比較になりエラーになります。Noneの判定は if data is None: と書くのがPythonの基本です。

組み込みの max() に配列と数値を渡している

「マイナスの値を0にしたい」と思って max(arr, 0) と書くと、組み込みの max() が配列と0を比べて大小を1つの真偽値にしようとするため、同じValueErrorになります。要素ごとに処理するなら np.maximum(arr, 0) または arr.clip(min=0) を使います。

import numpy as np
arr = np.array([3, -1, 4])
print(np.maximum(arr, 0))
print(arr.clip(min=0))
[3 0 4]
[3 0 4]

「boolean value of NA is ambiguous」は欠損値が原因

似たメッセージの TypeError: boolean value of NA is ambiguous は、配列ではなく欠損値 pd.NA を真偽値にしようとしたときのエラーです。Int64 などのnullable型の列で、欠損している要素を比較すると結果が <NA> になり、それをif文に入れると発生します(pandas: Working with missing data)。

import pandas as pd

s = pd.Series([1, None, 3], dtype="Int64")
for v in s:
    if v > 1:
        print(v)
TypeError: boolean value of NA is ambiguous

先に pd.notna(v) で欠損を除くか、Seriesのまま比較して fillna(False) で欠損をFalseに置き換えます。

import pandas as pd

s = pd.Series([1, None, 3], dtype="Int64")
for v in s:
    if pd.notna(v) and v > 1:
        print(v)
print(s[s.gt(1).fillna(False)])
3
2    3
dtype: Int64

原因と直し方の早見表

やりたいこと エラーになる書き方 正しい書き方
1つでも条件を満たすか if arr > 5: if (arr > 5).any():
すべて条件を満たすか if arr > 5: if (arr > 5).all():
条件の組み合わせで行を絞る df[(a) and (b)] df[(a) & (b)]
空かどうか if df: if df.empty: / arr.size > 0
1件の値で分岐 if s >= 80: if s.item() >= 80:
要素ごとに値を変える if文の関数にSeriesを渡す np.where() / apply()
配列全体が等しいか assert a == b np.array_equal(a, b)
Noneかどうか if data == None: if data is None:

エラーが出たら、トレースバックの最後に表示される自分のコードの行を見て、その行で「配列やSeriesを1つの真偽値として扱っていないか」を確認するのが近道です。

こうしたエラーは、1人で調べていると原因の切り分けに時間がかかりがちです。通学型プログラミングスクールのテックジム(東京本校は永田町)では、自分のペースで課題を進め、詰まったところをその場でトレーナーに質問できます。まずは無料講座で試してみるのも一つの方法です。

よくある質問

Q. 「Use a.any() or a.all()」はどちらを使えばいいですか?

判定したい内容で決めます。「1つでも条件を満たせばよい」なら any()、「すべてが条件を満たす必要がある」なら all() です。エラーを消す目的だけで選ぶと判定の意味が変わるので注意してください。

Q. pandasで and を使ったらエラーになりました。どう直せばいいですか?

and の代わりに &、or の代わりに |、not の代わりに ~ を使い、各条件を括弧で囲みます。例:df[(df[“score”] >= 70) & (df[“score”] < 90)]。括弧を省くと演算子の優先順位の関係で同じエラーが出ます。

Q. エラーメッセージにある a.bool() を使うとエラーになります。

Series.bool と DataFrame.bool は pandas 3.0 で削除されました。メッセージには今も候補として表示されますが、1件の値を取り出すなら .item() を使ってください。

Q. 「boolean value of NA is ambiguous」は同じエラーですか?

別のエラーです。こちらは配列ではなく欠損値 pd.NA を真偽値にしようとしたときに出る TypeError です。pd.notna() で欠損を除くか、fillna(False) で欠損を False に置き換えてから判定します。

Q. 要素が1つの配列だとエラーにならないのはなぜですか?

要素が1つなら真偽値が一意に決まるため、NumPyはそのまま True か False として扱います。データが1件のときは動き、件数が増えたとたんにエラーになることがあるので、件数に関係なく any()・all()・item() などで意図を明示しておくのが安全です。


pandas|設定・トラブル対応の関連記事

表示設定や、よく遭遇する警告・エラーの対処に関する記事です。

pandas全体の使い方は「pandasの使い方を初心者向けに解説」でまとめています。

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら