PythonでCSVを読み込む方法【製造業向け】Shift-JIS・複数ファイル対応コード付き

設備からエクスポートしたCSVをPythonで読み込もうとしたら、いきなり文字化けした——そんな経験はありませんか。

ネットで調べてコードをコピペしてみたものの、UnicodeDecodeError が出て止まった。あるいは、なぜかデータが1行ずれて読み込まれた。製造業の現場でPythonを触り始めた人が最初にぶつかる壁が、まさにここです。

私自身も製造業に関わる中で、設備から出力されたログCSVをPythonで読み込もうとして最初にぶつかったのがこのShift-JISエラーでした。メモ帳でファイルを開いて文字コードを確認してはじめて原因がわかった、という経験があります。汎用コードをコピペするだけでは動かない——これは製造業のCSVに特有の事情があるからなのです。

文字コードの違い、ヘッダーの形式、設備ごとのクセ——これらを知らないまま汎用コードをコピペすると高確率で詰まります。一方、問題の種類を把握すれば対処は難しくありません。

この記事では、製造現場のCSV(生産実績・検査データ・設備ログなど)をPythonで読み込むための実装コードを、よくある問題パターン別に解説します。

この記事を読むとできること

  • 製造業の現場CSVをpandasで読み込む基本を理解する
  • Shift-JIS・BOM付きCSVの文字コードエラーを解決する
  • ヘッダーなし・複数行ヘッダーのCSVに対処する
  • 月次フォルダにある複数ファイルを一括で読み込む
  • よくあるエラーの原因と直し方がわかる

製造業でPythonをどんな業務に活用できるか、まず全体像を確認したい方はこちらも参考にしてください。
製造業でPythonを使って自動化する方法|非エンジニアが現場で実践した5場面

製造業のCSVが「一般のCSV」と違う理由

一般的なPython入門記事のコードは、UTF-8・1行ヘッダー・数値列がきれいな数字——という前提で書かれています。ところが製造現場のCSVは、この前提が崩れていることが多いのです。

よくある3つの違いを先に把握しておくと、この後のコードがすんなり理解できます。

違い1:文字コードがShift-JIS(またはCP932)

日本の設備・ERPシステムから出力されるCSVの多くは、いまもShift-JIS(またはCP932)で保存されています。pandasのデフォルトはUTF-8なので、エンコーディングを指定しないとエラーになります。

違い2:ヘッダーがない、または複数行ある

設備ログCSVでは、1行目が機械名、2行目が計測条件、3行目からがデータ——という形式も珍しくありません。pandasはデフォルトで1行目をヘッダーとして扱うため、そのまま読み込むとデータがずれます。

違い3:数値列に文字が混入している

「測定不能」「-」「*」など、測定値が取れなかった場合のマーク文字が数値列に入っているケースがあります。このまま読み込むと列全体が文字列型(object型)として扱われ、計算できなくなります。

基本:pandasでCSVを読み込む

最短コード

まず、一番シンプルな読み込みから確認します。

import pandas as pd

df = pd.read_csv("data.csv")
print(df.head())

これが動けば問題なし。動かない場合は、次のパターン別コードに進んでください。

どのパターンから始めるか迷ったら、まずパターン1(Shift-JIS対応)から試してみてください。製造業のCSVの大半はこれで読めます。

読み込んだ後に最初に確認すること

print(df.head())    # 最初の5行を確認
print(df.dtypes)    # 各列の型を確認
print(df.shape)     # 行数・列数を確認

dtypes を見て数値列が object になっていたら、文字混入か文字コードの問題が起きています。

パターン別:製造業のCSVを読み込む実装コード

パターン1:Shift-JISのCSV(設備・PLCデータ)

このパターンが必要な場面: 設備・PLCのログ、温度・圧力センサーのログ、生産実績システムからのエクスポートCSVが該当します。製造業で最も頻繁に遭遇するパターンです。

encoding を指定するだけで解決します。

import pandas as pd

# Shift-JIS(CP932)で読み込む
df = pd.read_csv("seisan_jisseki.csv", encoding="cp932")

print(df.head())

cp932 は Windows 向け拡張 Shift-JIS で、日本の業務システムCSVにはほぼ対応できます。shift-jis で試してダメなら cp932 に変えてみてください。

BOM付きUTF-8(Microsoft製ツールからの出力に多い)の場合は encoding="utf-8-sig" を使います。

df = pd.read_csv("export.csv", encoding="utf-8-sig")

どちらかわからない場合の判断方法
メモ帳でファイルを開き、右下の文字コード表示を確認します。「ANSI」と表示されていればCP932、「UTF-8 BOM」と表示されていればutf-8-sigを使ってください。

パターン2:ヘッダーなしCSV

このパターンが必要な場面: 設備ログで1行目からデータが始まる形式、または古い帳票システムから出力される列名なしCSVが該当します。

# ヘッダーなし。列名を自分で設定する
df = pd.read_csv(
    "keisoku_log.csv",
    encoding="cp932",
    header=None,
    names=["日時", "温度", "圧力", "流量"]
)

print(df.head())

header=None でヘッダー行なしと宣言し、names= で列名を自分で付けます。自分の現場のCSVの列数・並び順に合わせて書き換えてください。

パターン3:複数行ヘッダーのCSV(生産実績表)

このパターンが必要な場面: 「1行目:機械名・ライン名、2行目:測定項目名、3行目からデータ」という生産実績表や品質管理帳票のCSVが該当します。

# 最初の2行をスキップして3行目をヘッダーとして使う
df = pd.read_csv(
    "seisan_hyou.csv",
    encoding="cp932",
    skiprows=2      # スキップする行数を調整
)

print(df.head())

skiprows=2 で最初の2行を読み飛ばします。何行スキップすれば良いかは、ExcelやメモハッドでCSVを開いて確認してください。

パターン4:月次フォルダにある複数ファイルを一括結合

このパターンが必要な場面: 月ごと・日ごとにフォルダが分かれていて複数のCSVが蓄積されている場合、または複数ラインからそれぞれCSVが出力される場合が該当します。

import pandas as pd
import glob

# フォルダ内の全CSVを読み込んでまとめる
files = glob.glob("2026年04月/*.csv")

df_list = []
for f in files:
    df = pd.read_csv(f, encoding="cp932")
    df_list.append(df)

df_all = pd.concat(df_list, ignore_index=True)
print(f"{len(files)}ファイルを結合しました。合計{len(df_all)}行")

glob.glob() でフォルダ内のCSVをまとめて取得し、ループで読み込んでから pd.concat() で1つに結合します。ファイル数が50〜100本あっても数秒で終わります。

この手法を日報集計に応用した実装例はこちらで詳しく解説しています。
日報をPythonで自動集計する方法【コピペOK】製造業・事務系向けの実装コード

パターン5:数値列に「-」「*」が混入している場合

このパターンが必要な場面: 検査データや品質管理CSVで、測定不能・測定省略を示す記号が数値列に入っているケースが該当します。中〜上級向けですが、検査データ系のCSVでは頻出です。

# na_values で欠損扱いにする文字を指定する
df = pd.read_csv(
    "kensa_data.csv",
    encoding="cp932",
    na_values=["−", "*", "測定不能", "NG"]
)

# 読み込み後に数値型へ変換する
df["測定値"] = pd.to_numeric(df["測定値"], errors="coerce")

print(df.dtypes)

na_values に欠損扱いにしたい文字を列挙すると、それらをNaN(空欄)として読み込みます。errors="coerce" は「変換できない値はNaNにする」という意味です。

よくあるエラーと対処法

UnicodeDecodeError が出る

UnicodeDecodeError: 'utf-8' codec can't decode byte ...

原因: ファイルがShift-JIS(CP932)なのに encoding を指定していない

対処: encoding="cp932" または encoding="utf-8-sig" を追加する

df = pd.read_csv("data.csv", encoding="cp932")

データが1行ずれて読み込まれる(ParserError / 列名がおかしい)

原因: ヘッダーが複数行、または不要な行が先頭にある

対処: skiprows= でスキップ行数を調整する。まずExcelでCSVを開いて何行目からデータが始まるか確認する

df = pd.read_csv("data.csv", encoding="cp932", skiprows=3)

数値列が object 型になる

原因: 列に数字以外の文字(「-」「*」「測定不能」など)が含まれている

対処: na_values で欠損扱いにする文字を指定し、読み込み後に pd.to_numeric() で型変換する

df["測定値"] = pd.to_numeric(df["測定値"], errors="coerce")

読み込んだデータで何をするか

CSVを読み込めたら、次は「そのデータで何をするか」です。製造業でよく使われる活用例を2つ紹介します。

在庫管理データの場合: 発注点を下回った品目を自動抽出してアラートを出す仕組みを作れます。
在庫管理をPythonで自動化する方法【コピペOK】Excel台帳から発注アラートまで実装

生産・日報データの場合: 複数ラインの実績を1つの集計表にまとめて毎週の報告資料を自動生成できます。
日報をPythonで自動集計する方法【コピペOK】製造業・事務系向けの実装コード

どちらも「CSVを読み込む」ことが出発点なので、このページのコードがそのまま使えます。

まとめ

迷ったらまずパターン1(Shift-JIS対応)から試してみてください。製造業のCSVの大半はこれで読み込めます。それで動かない場合に、パターン2〜5を順に確認する流れが一番効率的です。

製造業のCSVには、Shift-JIS・ヘッダー問題・数値列への文字混入という「一般記事のコードが動かない原因」が3つあります。これらはすべて pd.read_csv() の引数を適切に指定することで対処できます。

問題対処の引数
文字化け(Shift-JIS)encoding="cp932"
BOM付きUTF-8encoding="utf-8-sig"
ヘッダーなしheader=None + names=[...]
先頭行をスキップskiprows=N
欠損マーク文字na_values=[...]
複数ファイル結合glob.glob() + pd.concat()

なお、本記事が対象としているのはカンマ区切りCSVです。タブ区切り(TSV)や固定長テキスト形式は対応が異なります。それらが混在している場合は、まずファイルをメモ帳で開いて区切り文字を確認してみてください。

関連記事