PythonでCSVを読み込む際の落とし穴:カンマ後の空白に要注意!


CSV(Comma Separated Values)ファイルは、データを扱う上で非常に便利な形式です。しかし、一見シンプルなこの形式にも、Pythonで読み込む際に注意すべき落とし穴が存在します。その一つが、「カンマの後に空白があるCSV」です。

例えば、「apple, orange, grape」のように、カンマの直後に空白が含まれている場合、通常の読み込み方法では予期せぬ結果を招くことがあります。この記事では、PythonでCSVファイルを安全かつ正確に読み込むための、この落とし穴への対策と、短いサンプルコードをご紹介します。

なぜカンマ後の空白が問題になるのか?

多くのCSVパーサーやスプレッドシートソフトウェアは、カンマの後の空白を自動的に無視するか、適切に処理します。しかし、Pythonの標準ライブラリであるcsvモジュールや、データ分析でよく使われるpandasライブラリは、デフォルトの設定ではこの空白をデータの一部として扱ってしまうことがあります。

データの不整合

例えば、「"apple", " orange"」というCSVがあった場合、" orange"は「 orange」として読み込まれてしまいます。これは、文字列比較やデータ型変換の際に問題となり、意図しないエラーやデータの不整合を引き起こす可能性があります。

集計・分析の誤り

データベースにインポートする際や、データを集計・分析する際に、この余分な空白が原因でレコードがマッチしない、あるいは誤った結果が導き出されるといった事態が発生します。


Pythonでの対策:strip()skipinitialspace

Pythonでカンマ後の空白を含むCSVファイルを適切に処理するには、いくつかの方法があります。

1. strip()メソッドで空白を除去する

読み込んだ各要素に対して、文字列の先頭や末尾の空白を除去するstrip()メソッドを適用するのが最も基本的な方法です。これはcsvモジュールで1行ずつ処理する場合に有効です。

Python
 
import csv

csv_data = """name, city, age
Alice, Tokyo, 30
Bob, Osaka , 25
Charlie, Nagoya , 35
"""

# StringIOを使って文字列をファイルのように扱う
from io import StringIO
csvfile = StringIO(csv_data)

reader = csv.reader(csvfile)
header = [h.strip() for h in next(reader)] # ヘッダーも空白除去

data = []
for row in reader:
    # 各要素にstrip()を適用
    stripped_row = [item.strip() for item in row]
    data.append(stripped_row)

print("ヘッダー:", header)
print("データ:", data)

# 出力例:
# ヘッダー: ['name', 'city', 'age']
# データ: [['Alice', 'Tokyo', '30'], ['Bob', 'Osaka', '25'], ['Charlie', 'Nagoya', '35']]

この方法では、ヘッダーと各行の要素すべてに対して明示的にstrip()を適用しています。


2. csvモジュールのskipinitialspace=Trueを使う

csvモジュールには、カンマの後の空白を自動的に無視してくれる便利な引数**skipinitialspace**があります。これをTrueに設定するだけで、手動でstrip()する必要がなくなります。

Python
 
import csv
from io import StringIO

csv_data = """name, city, age
Alice, Tokyo, 30
Bob, Osaka , 25
Charlie, Nagoya , 35
"""

csvfile = StringIO(csv_data)

# readerにskipinitialspace=Trueを設定
reader = csv.reader(csvfile, skipinitialspace=True)

header = next(reader) # skipinitialspaceはヘッダーにも適用される
data = []
for row in reader:
    data.append(row)

print("ヘッダー:", header)
print("データ:", data)

# 出力例:
# ヘッダー: ['name', 'city', 'age']
# データ: [['Alice', 'Tokyo', '30'], ['Bob', 'Osaka', '25'], ['Charlie', 'Nagoya', '35']]

この方法が最も簡潔で推奨されます。


3. pandasskipinitialspace=Trueを使う

データ分析でデファクトスタンダードとなっているpandasライブラリにも、同様の機能があります。read_csv()関数のskipinitialspace引数を使用します。

Python
 
import pandas as pd
from io import StringIO

csv_data = """name, city, age
Alice, Tokyo, 30
Bob, Osaka , 25
Charlie, Nagoya , 35
"""

# read_csvにskipinitialspace=Trueを設定
df = pd.read_csv(StringIO(csv_data), skipinitialspace=True)

print(df)

# 出力例:
#       name     city  age
# 0    Alice    Tokyo   30
# 1      Bob    Osaka   25
# 2  Charlie  Nagoya    35

pandasを使う場合も、skipinitialspace=Trueを指定するだけで、自動的に空白が処理され、クリーンなデータフレームが得られます。


まとめとベストプラクティス

PythonでCSVファイルを読み込む際、カンマの後に空白があるデータに出くわすことは珍しくありません。このような状況に備えるためのベストプラクティスは以下の通りです。

  1. csvモジュールを使用する場合:

    • csv.readerまたはcsv.DictReaderに**skipinitialspace=True**を設定することを強く推奨します。これが最も効率的で間違いのない方法です。

    • もし何らかの理由でskipinitialspaceが使えない場合は、読み込んだ各要素にitem.strip()を手動で適用します。

  2. pandasを使用する場合:

    • pd.read_csv()に**skipinitialspace=True**を設定します。pandasは内部でCパーサーを使用しており、高速に処理できます。


これらの対策を講じることで、カンマ後の空白による予期せぬエラーを防ぎ、データの正確性と信頼性を向上させることができます。CSVファイルを扱う際は、常にこの「カンマ後の空白」に注意し、適切な読み込み方法を選択するようにしましょう。

「らくらくPython塾」が切り開く「呪文コーディング」とは?

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座