pandas.parser.CParserError: Error tokenizing data の原因と直し方【Dockerで検証済み】
pandas.parser.CParserError: Error tokenizing data の原因と解決方法。検証済みの解決コマンド付きで、現象→原因→解決→確認の順に最短で直せます。
発生したエラー
pandas.parser.CParserError: Error tokenizing data結論:まずこれで直ります
pandas の CParserError(現在の pandas では ParserError)は、CSVファイルの各行の列数がヘッダー行の列数と一致しない場合に発生します。下の解決コマンドを順に実行すれば直ります。
cat << 'EOF' > /tmp/fix_csv.py
import pandas as pd
# error_bad_lines=False は古いAPI。on_bad_lines='skip' で不正行をスキップするか、
# engine='python' + on_bad_lines='warn' で警告表示しつつ読み込む。
# 根本解決: CSVの列数不一致を修正してから読み込む。
# まず列数の不整合を確認・修正する
fixed_lines = []
with open('/tmp/broken.csv', 'r') as f:
lines = f.readlines()
header = lines[0]
num_cols = len(header.strip().split(','))
print(f'Expected columns: {num_cols}')
for i, line in enumerate(lines):
cols = line.strip().split(',')
if len(cols) != num_cols:
print(f'Line {i+1} has {len(cols)} columns (expected {num_cols}): {line.strip()}')
# 列が少ない場合は空文字で補完、多い場合は余分をカット
if len(cols) < num_cols:
cols += [''] * (num_cols - len(cols))
else:
cols = cols[:num_cols]
fixed_lines.append(','.join(cols) + '\n')
with open('/tmp/fixed.csv', 'w') as f:
f.writelines(fixed_lines)
# 修正済みCSVを読み込む
df = pd.read_csv('/tmp/fixed.csv')
print('\nSuccessfully loaded DataFrame:')
print(df)
EOF
python3 /tmp/fix_csv.py現象どんなエラーか
次の操作を行うと(検証環境: python:3.11)、上記のエラーが発生します。まずは下の再現コマンドで、同じ状況を再現できることを確認してください。
検証環境:python:3.11
pip install pandas -q
cat << 'EOF' > /tmp/broken.csv
name,age,city
Alice,30,Tokyo
Bob,25
Charlie,35,Osaka,Japan
EOF
python3 -c "
import pandas as pd
df = pd.read_csv('/tmp/broken.csv')
print(df)
"原因なぜ起きるのか
pandas の CParserError(現在の pandas では ParserError)は、CSVファイルの各行の列数がヘッダー行の列数と一致しない場合に発生します。例えば、ヘッダーが3列なのにデータ行が2列しかなかったり、逆に4列あったりすると、デフォルトのCパーサーがエラーを投げます。 根本的な解決策はCSVデータそのものの不整合を修正することです。具体的には、各行を読み込んでヘッダーの列数と比較し、不足している場合は空文字で補完し、余分な場合は切り詰めてから正しいCSVとして書き直します。その後、整合性の取れたCSVファイルを通常通り pd.read_csv() で読み込みます。 応急処置として on_bad_lines='skip' や engine='python' を使う方法もありますが、データが欠落するリスクがあるため、可能であればデータの出所を確認して正しいフォーマットで出力し直すことが最善策です。
解決解決手順
cat << 'EOF' > /tmp/fix_csv.py
import pandas as pd
# error_bad_lines=False は古いAPI。on_bad_lines='skip' で不正行をスキップするか、
# engine='python' + on_bad_lines='warn' で警告表示しつつ読み込む。
# 根本解決: CSVの列数不一致を修正してから読み込む。
# まず列数の不整合を確認・修正する
fixed_lines = []
with open('/tmp/broken.csv', 'r') as f:
lines = f.readlines()
header = lines[0]
num_cols = len(header.strip().split(','))
print(f'Expected columns: {num_cols}')
for i, line in enumerate(lines):
cols = line.strip().split(',')
if len(cols) != num_cols:
print(f'Line {i+1} has {len(cols)} columns (expected {num_cols}): {line.strip()}')
# 列が少ない場合は空文字で補完、多い場合は余分をカット
if len(cols) < num_cols:
cols += [''] * (num_cols - len(cols))
else:
cols = cols[:num_cols]
fixed_lines.append(','.join(cols) + '\n')
with open('/tmp/fixed.csv', 'w') as f:
f.writelines(fixed_lines)
# 修正済みCSVを読み込む
df = pd.read_csv('/tmp/fixed.csv')
print('\nSuccessfully loaded DataFrame:')
print(df)
EOF
python3 /tmp/fix_csv.py確認直ったか確認する
python3 -c "
import pandas as pd
df = pd.read_csv('/tmp/fixed.csv')
assert len(df) == 3, f'Expected 3 rows, got {len(df)}'
assert list(df.columns) == ['name', 'age', 'city'], f'Unexpected columns: {df.columns.tolist()}'
print('Verification passed:', df.shape)
"動画で見る
この記事の解決手順は実環境で検証しています
山田 英紀(社内SE 5年以上・13業種以上の業務システムを開発/運用)が、 掲載コマンドを検証環境で実行し、再現〜解決〜確認まで通ることを確認しています。