Python基礎 実案件/ポートフォリオ

もう事故らせない:PythonでCSV/JSON/Excelを安全に読み書きする実務レシピ

CSV/JSON/Excelの読み書き、どこから気をつければいい?

文字化け・先頭ゼロ欠落・壊れたExcel……もう事故らせたくない!

結論:データ仕事の9割はI/O(入出力)。ここを整えるだけで、桁落ち・文字化け・先頭ゼロ欠落・Excel破損・巨大CSVでフリーズといった“現場の事故”を大幅に減らせます。本稿はpythonbunseki.comの実務テイストで、CSV/JSON/Excelの安全な読み方・壊さない書き方、型/エンコーディング/改行の落とし穴回避、そして大きなデータを速く回すコツを、コピペで使えるコード付きで解説します。

この記事で身に付く力

  • CSV/JSON/Excelを“正しく読む・壊さず書く”実務レシピ
  • 型・エンコーディング・改行の罠回避と再発防止テンプレ
  • 巨大ファイルを速く回す:チャンク/Parquet/原子置換

関連記事:
>>【保存版】pandas基礎:データフレームの作成・整形・結合・集計を“実務の型”で身につける
>>【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得
>>【保存版】Jupyter Notebookの基本:環境構築・使い方・再現性・“読みやすいノート”設計まで完全ガイド
>>Python実務の型:例外処理と構造化ログでエラーに強いコードを書く
>>【保存版】SQLite×Pythonで作る“ローカルDWH”——ETL・集計・レポート自動化の最短手順
>>データ可視化レポート納品の型:Tableau/Matplotlib|“図3点+結論1行+運用”で伝わる・続く・刺さる

よくある5つの事故(まずここを潰す)

  • 文字化け:UTF-8/BOM/CP932(Shift_JIS)の誤判定。濁点や絵文字が崩れる。
  • 先頭ゼロ欠落:郵便番号や商品コードが00123 → 123になる。
  • 日付が文字列のままobject型で集計できない。
  • Excelが壊れる:エンジン不一致、数式/書式の消失、巨大ファイルでクラッシュ。
  • 重すぎて落ちる:数百万行CSVを一気読みしてNotebookが固まる。

ふみとの現場メモ

データサイエンティストとして10年・100件超の伴走で、事故が減る順序は明確でした。①pathlibでパス統一 → ②読み込みでdtype/usecols/parse_datesを明示 → ③書き込みは一時ファイル→原子置換 → ④中間はParquet → ⑤pytest×tmp_pathでラウンドトリップ検証。この記事はこの型に沿って進めます。

共通レシピ:パス・原子置換・ログ

まずは「壊れない書き込み」の土台から。書き途中の中断や電源断で破損しないよう、一時ファイル→os.replaceで原子的に置換します。

from pathlib import Path
import tempfile, os, logging
log = logging.getLogger(__name__)

def atomic\_write\_text(path: Path, text: str, encoding: str = "utf-8") -> None:
path.parent.mkdir(parents=True, exist\_ok=True)
with tempfile.NamedTemporaryFile("w", delete=False, dir=path.parent, encoding=encoding, newline="") as tmp:
tmp.write(text)
tmp\_path = Path(tmp.name)
os.replace(tmp\_path, path)

CSV:エンコーディング/改行/型の三点セット

先頭ゼロ保護日付の即時datetime、そして列絞りで軽く読みます。文字化けしたらまずcp932を試すのが日本の業務鉄板。

import pandas as pd
from pathlib import Path

p = Path("data/sales.csv")
usecols = \["date","store","sku","qty","price"]
dtypes  = {"store":"category","sku":"string","qty":"int32","price":"float32"}
na\_vals = \["","NA","N/A","null","-","--"]

df = pd.read\_csv(
p,
encoding="utf-8",     # ダメなら 'cp932'
usecols=usecols,      # メモリ節約
dtype=dtypes,         # 先頭ゼロ保護=string
na\_values=na\_vals,
parse\_dates=\["date"], # 日付→datetime
thousands=",",        # 3桁区切り除去
skip\_blank\_lines=True
)

巨大CSVチャンク読みで集計だけ溜めるのが安全で速いです。

agg = {}
for chunk in pd.read_csv(p, usecols=usecols, dtype=dtypes, parse_dates=["date"], chunksize=200_000):
    g = chunk.groupby("store").qty.sum()
    for k, v in g.items():
        agg[k] = agg.get(k, 0) + int(v)

書き出し時は改行エンコーディングを明示。Windowsで余計な空行が入る問題はnewline=""で回避できます。

# pandas → CSV
from pathlib import Path
out = Path("out/sales_clean.csv")
df.to_csv(out, index=False, encoding="utf-8", line_terminator="\n")

# 標準csvで厳密制御(空行問題の回避)

import csv
rows = \[\["sku","qty"],\["00123",10],\["A-9",5]]
with Path("out/items.csv").open("w", encoding="utf-8", newline="") as f:
w = csv.writer(f, quoting=csv.QUOTE\_MINIMAL)
w\.writerows(rows)

JSON:構造化・NDJSON・精度の罠

json.dumps()ensure_ascii=Falseで日本語をそのまま、indent/sort_keysでレビューしやすく。大量ログは行ごとJSON(NDJSON)が相性◎。

import json
from pathlib import Path

p = Path("data/config.json")
config = json.loads(p.read\_text(encoding="utf-8"))

# or:

with p.open("r", encoding="utf-8") as f:
config = json.load(f)

text = json.dumps(config, ensure\_ascii=False, indent=2, sort\_keys=True)
Path("out/config.json").write\_text(text, encoding="utf-8")

# NDJSON(1行=1JSON)

import pandas as pd
df = pd.read\_json("data/events.ndjson", lines=True)
Path("out/events.ndjson").write\_text(
"\n".join(df.to\_json(orient="records", lines=True).splitlines()),
encoding="utf-8"
)

Excel:エンジン/書式/複数シートの基本

.xlsxは読みopenpyxl、書きopenpyxl/xlsxwriterが基本。コード列はstring先頭ゼロ保護を。

import pandas as pd
from pathlib import Path

# 読む

p = Path("data/report.xlsx")
df = pd.read\_excel(p, sheet\_name="売上", usecols="A\:F",
dtype={"店舗":"category","商品コード":"string"})

# 書く:複数シート+書式

with pd.ExcelWriter(Path("out/report.xlsx"), engine="xlsxwriter") as w:
df\_summary.to\_excel(w, sheet\_name="サマリ", index=False)
df\_detail.to\_excel(w, sheet\_name="明細", index=False)
wb  = w\.book
ff  = wb.add\_format({"bold": True})
num = wb.add\_format({"num\_format": "#,##0"})
ws1 = w\.sheets\["サマリ"]
ws1.set\_row(0, None, ff)
ws1.set\_column("D\:D", None, num)

高速化:Parquet/型詰め/チャンク

中間はCSVよりParquetが速くて軽い。ついでにdowncastcategory化でメモリ1/2〜1/4へ。

import pandas as pd

df.to\_parquet("work/data.parquet", compression="zstd")
df2 = pd.read\_parquet("work/data.parquet")

def optimize\_dtypes(df: pd.DataFrame) -> pd.DataFrame:
for c in df.select\_dtypes(include="int64").columns:
df\[c] = pd.to\_numeric(df\[c], downcast="integer")
for c in df.select\_dtypes(include="float64").columns:
df\[c] = pd.to\_numeric(df\[c], downcast="float")
for c in df.select\_dtypes(include="object").columns:
if df\[c].nunique() / max(len(df),1) < 0.5:
df\[c] = df\[c].astype("category")
return df

フォルダ一括処理:日次CSVの連結

from pathlib import Path
import pandas as pd

root = Path("data/daily")
files = sorted(root.glob("sales\_2025-\*.csv"))

frames = \[]
for p in files:
df = pd.read\_csv(p, usecols=\["date","store","sales"], parse\_dates=\["date"], dtype={"store":"string"})
df\["source"] = p.name
frames.append(df)
all\_df = pd.concat(frames, ignore\_index=True)

エラーハンドリング:境界ごとに例外ラップ

from pathlib import Path
import pandas as pd

class DataError(Exception): ...
class ExternalError(Exception): ...

def load\_csv\_safe(path: Path) -> pd.DataFrame:
try:
return pd.read\_csv(path, encoding="utf-8")
except UnicodeDecodeError as e:
raise DataError(f"encoding error: {path}") from e
except OSError as e:
raise ExternalError(f"file io error: {path}") from e

ふみとの体験談:SJISの落とし穴

昔、社内システムがCP932(SJIS)固定で、外部ベンダはUTF-8。濁点が消える事故が連発し、顧客名マッチングが壊滅しました。以降は「まずUTF-8、無理ならCP932で仮読み→持ち主に確認」「先頭ゼロ列はstring」を徹底し、納品時は原子置換で壊れないようにしています。

よくある罠と対処(早見表)

症状原因対処
文字化けエンコーディング違いencoding="cp932"errors="ignore"で仮読み→持ち主確認
先頭ゼロ欠落自動型変換読み:dtype="string"、書き:Excelの表示形式=文字列
カンマ付き数値区切り記号thousands=","/書きは{:,}で整形
巨大CSVで落ちる一括読みchunksizeusecols・Parquet化
read_excelが遅いエンジン/列過多usecolsで範囲指定、必要ならengine="openpyxl"明示
JSON桁落ちfloat誤差decimal.Decimal、または文字列保持
改行が倍増Windowsの改行制御open(..., newline="")で回避

ユースケース別の第一手(絞り込み)

  • 社内定例のCSV→Excel配布pandas→ExcelWriter(xlsxwriter)サマリ/明細の2枚出力 → [内部リンク:データ可視化レポート納品の型]
  • APIログのNDJSON集計read_json(lines=True)groupby→Parquet保存
  • レガシーSJIS CSVencoding="cp932"dtype="string"先頭ゼロ保護
  • 巨大CSV連結chunksize+列絞り+集計のみ保持(生データはParquetへ)

今日やること(45分)

  1. あなたの実データ1本を、usecols/dtype/parse_datesを明示して読み込む
  2. 先頭ゼロ列をstring化、中間Parquetで保存して速度を体感
  3. ExcelWriter(xlsxwriter)サマリ/明細の2シートを出力
  4. pytest×tmp_pathCSVラウンドトリップのテストを1本作る

テスト:pytest×tmp_path(コピペ)

import pandas as pd

def test\_csv\_roundtrip(tmp\_path):
p = tmp\_path/"a.csv"
df = pd.DataFrame({"sku":\["001","002"],"qty":\[1,2]})
df.to\_csv(p, index=False, encoding="utf-8")
back = pd.read\_csv(p, dtype={"sku":"string"})
assert list(back.sku) == \["001","002"]

伴走のご案内:I/Oの型を整えて“壊れない納品”へ

I/Oは設計で9割決まる。無料カウンセリング/体験で、あなたのデータ仕様に合わせたエンコーディング/型/Parquet/Excel体裁を設計し、原子置換まで組み込んだ納品テンプレを作ります。

TechAcademy データサイエンスコース(受講料:174,600円~ ※更に割引あり)

TechAcademy 無料相談

株式会社キカガク AI人材長期育成コース(受講料:237,600円~)

キカガク 無料相談

この記事から次に読む(内部リンク)

スキルアップ
【保存版】pandas基礎:データフレームの作成・整形・結合・集計を“実務の型”で身につける

データ分析の9割は前処理と整形です。ここをpandasで素早く正確にこなせるかが、成果物の質と速度を決めます。本記事は未経験〜初学者が週10時間×2〜3週で、pandasの基礎(読み込み/選択/整形/ ...

スキルアップ
【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得

リード(結論)基礎を終えたら次は実務の現場で頻出する処理を“型”で覚える段階です。本記事は、pandas 2.x を前提に、欠損・外れ値・結合・ウィンドウ関数・時系列・カテゴリ処理・集計の自動化・大規 ...

SQLite
【保存版】SQLite×Pythonで作る“ローカルDWH”——ETL・集計・レポート自動化の最短手順

ローカルでゼロ構築、ファイル1つで完結、サーバ不要。本記事はSQLite×Pythonで“毎日回る”ETL・集計・レポート自動化を最短で作るための完全ガイドです。データ設計→DB作成→ETL(取り込み ...

可視化
【保存版】可視化入門:Matplotlib/Plotlyの使い分けと“伝わるグラフ設計”10ステップ

結論:可視化は「きれいに描く」ことではなく、意思決定を動かすための設計です。本稿では、未経験〜初学者が 週10時間×1〜2週 で、Matplotlib/Plotlyを軸に “伝わるグラフ”の設計と実装 ...

納品の型
データ可視化レポート納品の型:Tableau/Matplotlib|“図3点+結論1行+運用”で伝わる・続く・刺さる

結論:レポートは「データ→図」ではなく「意思決定→図」の順で設計します。最短で伝わり、運用で続く“型”は、(1) 結論1行、(2) 図3点(推移・分解・構成)、(3) 打ち手(閾値/費用対効果)、(4 ...

最近のコメント

    • この記事を書いた人
    • 最新記事

    ふみと

    このブログでは、データサイエンティストとして市場価値を上げる方法を独自にまとめて発信しています。

    【プロフィール】
    ・大手企業データサイエンティスト/マーケティングサイエンティスト(10年、年収900万円台)/案件100件以上
    ・資格:JDLA E資格(日本ディープラーニング協会主催)/JDLA Community(CDLE会員)/Advanced Marketer/ビジネス統計スペシャリスト/統計検定2級/TOEIC 805
    ・スキル:Python/Tableau/SQL/機械学習/Deep Learning/RPA

    -Python基礎, 実案件/ポートフォリオ