金額列に「不明」が一件混ざるだけで、数値への変換が止まることがあります。止まった場所だけを直して繰り返すより、変換できない値をまとめて返すと、入力元へ確認する場所を伝えやすくなります。
pandasのto_numericにerrors="coerce"を渡すと、数値にできない値は欠損値になります。ただし、それだけでは元からの空欄と区別できません。変換前の値と空欄の判定を残すことで、二つを別の一覧にします。
元の文字と変換結果を並べる
次は金額1200、空欄、不明、0の四件を使います。IDも金額も架空です。前後の空白を除いた値を変換対象とし、空文字だけを未入力とする条件にしています。
import pandas as pd
df = pd.DataFrame({
"ID": ["T1", "T2", "T3", "T4"],
"金額": ["1200", "", "不明", "0"],
})
text = df["金額"].astype("string").str.strip()
blank = text.eq("")
number = pd.to_numeric(text.where(~blank), errors="coerce")
invalid = number.isna() & ~blank
bad_values = df.loc[invalid, ["ID", "金額"]]
print("変換失敗の値:", bad_values.to_dict("records"))
print("元から空欄のID:", df.loc[blank, "ID"].tolist())
print("数値の参考合計:", int(number.sum()))
assert bad_values.values.tolist() == [["T3", "不明"]]
assert df.loc[blank, "ID"].tolist() == ["T2"]
assert number.iloc[3] == 0
変換失敗はT3の「不明」、元から空欄はT2です。0は正常な数値として残ります。参考合計は1200ですが、不備のある入力を正式な集計として確定するための値ではありません。実際の処理では、確認対象が残る間は保存や配信へ進めない条件を設けられます。
掲載コードはWindows・Python 3.12.10・pandas 3.0.2で実行しました。この四件について、空欄と変換失敗を分け、0を保持することを確認しています。
coerceは修正する機能ではない
coerceは数に読めない値を数値へ直してくれる指定ではありません。「1,200円」を1200と理解したり、「約100」を業務上正しい金額へ決めたりする処理は含みません。
カンマを除く、通貨記号を外す、全角数字を直すといった前処理を加える場合は、対象列と認める形式を決めます。見た目の記号を一律に削ると、異なる通貨や誤入力まで同じ値にしてしまうことがあります。
今回のstripも、前後の空白は意味を持たないという例の条件です。コードや文章に同じ処理を無条件で適用するための設定ではありません。
確認表には元値も残す
IDだけを表示しても、入力元の表から探し直す手間は残ります。上の例ではIDと元の値を同じレコードに並べています。変換後の状態も同じ確認表へ残せます。元の金額列を上書きしなければ、なぜ止めたかを後から説明できます。
一方で、氏名や自由記述まで同じ確認表へコピーする必要があるかは分けて考えます。入力の修正に必要な列へ絞ると、共有先の判断もしやすくなります。
to_numericは非常に大きな整数で精度が失われる可能性があります。商品コードや長い番号を数値へ変換する用途には、そのまま使わないでください。また、金額を厳密な小数で計算する要件では、数値へ読めたことだけで計算精度を判断しません。
表の扱いはpandas入門、入力元による列名の違いはCSV列名の揺れを吸収する方法で補えます。
参考資料
pandas.to_numericとpandas.read_csvの公式資料を確認しました。資料確認日は2026年11月1日です。
