「型を決めてから読む」という発想を持つ
Excelは何でも受け入れてくれるので、同じ列に数字・文字・空白が混ざっていることがよくあります。
そのまま read_excel に任せると、pandasが「たぶんこうだろう」と推測して型を決めますが、それがこちらの意図とズレることが多いです。
そこで使うのが dtype です。dtype={"col": str} のように指定すると、「この列はこういう型で読んでくれ」と、こちらからはっきり指示できます。
読み込み時に型を決めておくと、その後の処理が安定し、バグも減ります。
基本形:dtype={‘col’: str} の意味を理解する
最小コードと挙動
import pandas as pd
df = pd.read_excel(
"customers.xlsx",
dtype={"CustomerID": str}
)
print(df.dtypes)
print(df.head())
Pythonここで dtype={"CustomerID": str} と書くことで、「CustomerID 列は文字列として読み込む」と指定しています。
Excel側で数値っぽく見えていても、先頭ゼロがあっても、必ず文字列として扱われます。
重要なのは、「pandasに推測させない」という姿勢です。
ID・コード・郵便番号など、「数値っぽいけど計算しないもの」は、基本的に文字列で読む、と決めてしまうと安定します。
複数列をまとめて指定する
df = pd.read_excel(
"orders.xlsx",
dtype={
"OrderID": str,
"CustomerID": str,
"ZipCode": str
}
)
print(df.dtypes)
Pythonこのように、辞書で複数列を一度に指定できます。
「このファイルでは、これらの列は全部文字列で扱う」というルールを、読み込み時に宣言しているイメージです。
よく使う型指定パターン
コード・ID・郵便番号を文字列で読む
import pandas as pd
df = pd.read_excel(
"master.xlsx",
dtype={
"商品コード": str,
"顧客ID": str,
"郵便番号": str
}
)
print(df.dtypes)
Pythonここが一番重要です。
これらを数値として読むと、先頭ゼロが消えたり、桁数が変わったりして、後で結合や検索がうまくいかなくなります。
「計算しない数値っぽい列は、全部文字列にする」
このルールを持っておくだけで、かなりのトラブルを避けられます。
整数列に欠損がある場合(nullable 整数型)
pandasの通常の int64 型は「欠損(NaN)を持てない」という制約があります。
数量や個数の列に欠損があり得る場合は、Int64(大文字I)という「欠損を許容する整数型」を使います。
import pandas as pd
df = pd.read_excel(
"sales.xlsx",
dtype={
"数量": "Int64" # 欠損ありの整数
}
)
print(df.dtypes)
print(df["数量"].isna().sum())
Python"Int64" を使うと、欠損は NaN のまま、値は整数として扱えます。
「全部埋まっているはず」と思っていても、現場データには平気で空欄が混ざるので、数量系は最初から "Int64" を想定しておくと安全です。
浮動小数点(小数を含む数値)
単価や金額(小数あり)などは、float で指定できます。
import pandas as pd
df = pd.read_excel(
"prices.xlsx",
dtype={
"単価": float,
"割引率": float
}
)
print(df.dtypes)
Pythonただし、Excel側に文字や記号が混ざっていると、dtype=float で読み込み時にエラーになることがあります。
その場合は、いったん文字列で読み込んでから pd.to_numeric(..., errors="coerce") で変換する方が安全です。
dtype と parse_dates・converters の関係
日付は dtype ではなく parse_dates で扱う
日付列を dtype=str にしてしまうと、毎回自分で to_datetime する必要が出てきます。
日付は dtype ではなく parse_dates で指定するのが基本です。
import pandas as pd
df = pd.read_excel(
"sales.xlsx",
dtype={"CustomerID": str},
parse_dates=["Date"]
)
print(df.dtypes)
Pythonここでは、「CustomerID は文字列」「Date は datetime64[ns]」という形で読み込まれます。
日付列があるなら、まず parse_dates を検討し、それ以外の列に dtype を使う、という順番で考えると整理しやすくなります。
複雑な変換は converters と併用する
カンマ付き金額や単位付き数値など、「そのままでは数値にならない」列に対しては、dtype だけでは足りません。
その場合は converters で加工しつつ、結果の型を揃えます。
import pandas as pd
def clean_amount(x):
if pd.isna(x):
return None
s = str(x).replace(",", "").replace("円", "").strip()
return float(s) if s else None
df = pd.read_excel(
"sales.xlsx",
dtype={"顧客ID": str},
converters={"金額": clean_amount}
)
print(df.dtypes)
Pythonここでは、「顧客IDは文字列」「金額は converters で float に変換」という役割分担になっています。dtype は「そのまま型を決められる列」に、converters は「加工が必要な列」に、という使い分けがポイントです。
実践テンプレートでイメージを固める
テンプレ1:顧客マスタを「文字列中心」で安定して読む
import pandas as pd
df = pd.read_excel(
"customer_master.xlsx",
dtype={
"CustomerID": str,
"ZipCode": str,
"Phone": str
}
)
print(df.dtypes)
print(df.head())
Pythonこのテンプレートは、「結合キーや連絡先情報を、絶対に壊したくない」場面で使います。
数値として計算しない列は、最初から文字列にしておくのが鉄則です。
テンプレ2:売上明細を「IDは文字列・数量は整数・金額は数値」で読む
import pandas as pd
df = pd.read_excel(
"sales_detail.xlsx",
dtype={
"OrderID": str,
"CustomerID": str,
"Qty": "Int64"
},
parse_dates=["Date"]
)
df["Amount"] = pd.to_numeric(df["Amount"], errors="coerce")
print(df.dtypes)
print(df.head())
Pythonここでは、
- ID系は文字列
- 数量は欠損許容の整数
- 日付は datetime
- 金額は後から数値化
という、かなり現実的な型設計になっています。
このレベルまで読み込み時に決めておくと、後の集計や結合が非常にスムーズになります。
つまずきやすいポイントと注意点
dtype を厳しく指定しすぎて読み込み時にエラーになる
例えば、dtype={"Qty": int} としているのに、Excel側に空欄や文字が混ざっていると、読み込み時にエラーになります。
数量系は最初から "Int64"(nullable 整数)にしておくか、いったん文字列で読み込んでから to_numeric(errors="coerce") で変換する方が安全です。
文字列にしたら数値計算がしづらくなった
IDやコードは文字列で良いですが、本当に計算したい列まで str にしてしまうと、毎回変換が必要になります。
「計算する列」と「計算しない列」を頭の中で分けておき、計算する列は float や "Int64"、計算しない列は str、という整理をしておくと迷いにくくなります。
dtype と parse_dates を同時に同じ列に指定しない
同じ列に対して dtype と parse_dates を両方指定すると、意図しない挙動になることがあります。
日付は parse_dates に任せ、dtype では触らない、というルールにしておくとシンプルです。
小さな練習問題
練習1:customers.xlsx を「ID・郵便番号・電話番号は文字列」で読む
条件は次の通りです。
CustomerID,ZipCode,Phoneをすべて文字列で読む- 読み込み後に
df.dtypesを表示して、型が想定通りか確認する
自分でコードを書いてみて、「どの列を文字列にすべきか」を意識してみてください。
練習2:sales.xlsx を「IDは文字列・数量は欠損許容整数・日付は datetime」で読む
条件は次の通りです。
OrderID,CustomerIDを文字列で読むQtyを"Int64"で読むDateをparse_datesで datetime にする- 読み込み後に
df.dtypesとdf.head()を確認する
ここまでできると、「読み込み時に型を設計する」という感覚がかなり身についてきます。
最後に
dtype={'col': str} は、「この列はこう扱う」というあなたの意思表示です。
pandasに推測させるのではなく、自分で型を決めることで、
- 先頭ゼロが消えない
- 結合キーが壊れない
- 集計や変換が安定する
という、とても大きなメリットが得られます。
「この列は本当に数値として計算したいのか? それとも、ただのラベルか?」
それを一つずつ考えながら dtype を書いていくと、Excel処理の精度と安心感が一段上がります。
