CSVを読み込んだときに、数値のはずの列が object 型になっていて困ったことはないでしょうか。 pandas astype() は、列やDataFrameの型を明示的に変えるときによく使う基本機能です。
ただし、astype(int) をそのまま使うとエラーになることがあります。 そのため、「いつ astype() を使うのか」と「失敗しやすい場面では何を選ぶのか」を整理しておくことが大切です。
この記事では、pandas astype() の基本から、文字列・整数・小数への変換、よくあるエラー、to_numeric() や convert_dtypes() との違いまで、初心者向けにやさしく解説します。 Pandasの前処理で迷ったときに、「結局どう使えばいいのか」がわかる内容に絞って進めます。
この記事でわかること
pandas astype()の基本的な役割- 文字列・整数・小数への型変換のやり方
- 1列だけ変える方法と、複数列をまとめて変える方法
astype(int)が失敗しやすい理由to_numeric()、convert_dtypes()、infer_objects()との違い- データ分析の前処理で、型変換がどの場面で役立つか
pandas astype()とは?まず押さえたい基本
astype() は、Pandasの列やDataFrameのデータ型を明示的に変更するメソッドです。
たとえば、次のような場面で使います。
- 数値として扱いたい列が文字列になっている
- コード列を文字列としてそろえたい
- 小数が入った列を
floatとして扱いたい - 複数列の型をまとめて整えたい
データ分析では、まず head() や info() で全体像を見てから前処理に進むことが多いです。 その流れの中で astype() は、「この列の型をこうしたい」と自分で明示して整える操作として役立ちます。
逆にいうと、値がきれいにそろっていない列に対しては、そのまま astype() を使うと失敗しやすいです。 その点が、初心者がつまずきやすいポイントでもあります。
最初に覚えたい判断基準
初心者のうちは、まず次のように考えると混乱しにくいです。
- 見た目は数字でも
object型になっている列を、自分で型指定して整えたい →astype() - 数字以外の文字や記号が混ざっていそうで、そのまま変換するのが不安 →
pd.to_numeric() - CSV読込直後に列の状態を確かめたい → 先に
info()やhead()で確認する
特に read_csv() の直後は、想像よりも object 型の列が残っていることがあります。 そのため、「先に確認してから整える」という流れで読むと、この記事の内容が実務にもつながりやすくなります。
サンプルデータを作成して型を確認してみよう
まずは、型変換でよくある悩みを含んだサンプルデータを作成します。 売上や商品コードのような、データ分析でよくありそうな列を使います。
import pandas as pd
df = pd.DataFrame({
"商品コード": [1001, 1002, 1003, 1004],
"売上": ["1200", "980", "error", "1500"],
"数量": ["10", "8", "5", "12"],
"カテゴリ": ["食品", "日用品", "食品", "家電"]
})
print("元のDataFrame")
display(df)
print("\n元のデータ型")
df.info()
元のDataFrame
| 商品コード | 売上 | 数量 | カテゴリ | |
|---|---|---|---|---|
| 0 | 1001 | 1200 | 10 | 食品 |
| 1 | 1002 | 980 | 8 | 日用品 |
| 2 | 1003 | error | 5 | 食品 |
| 3 | 1004 | 1500 | 12 | 家電 |
元のデータ型 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null int64 1 売上 4 non-null object 2 数量 4 non-null object 3 カテゴリ 4 non-null object dtypes: int64(1), object(3) memory usage: 260.0+ bytes
実行すると、売上 と 数量 は見た目が数字でも object 型になっていることがあります。 CSV読込後にはこのような状態がよく起こります。
object型とは?初心者向けにざっくり理解しよう
object 型は、Pandasで文字列や、型がそろっていないデータが入っている列によく見られる型です。
たとえば、見た目は数字だけの列でも、途中に文字が1つ混ざっていたり、空欄が含まれていたりすると、数値型ではなく object 型になることがあります。
今回のサンプルデータでも、売上 列には "1200" や "980" のような数字に見える文字列に加えて、"error" も含まれています。 このような列は、Pandasが「きれいな数値列ではない」と判断しやすいため、object 型として扱われます。
object 型のままだと、平均や合計を計算しにくかったり、あとで集計するときに困ることがあります。 そのため、astype() や pd.to_numeric() を使って、扱いやすい型に整えることが大切です。
この段階で info() を見ると、どの列の型を直す必要があるかがわかりやすくなります。
pandas astype()の基本的な使い方
まずは一番基本の形を押さえましょう。
df["列名"] = df["列名"].astype(変換したい型)
たとえば、数量を文字列から整数に変えるなら次のように書きます。
df_basic = df.copy()
df_basic["数量"] = df_basic["数量"].astype(int)
display(df_basic)
print("\n変換後のデータ型")
df_basic.info()
| 商品コード | 売上 | 数量 | カテゴリ | |
|---|---|---|---|---|
| 0 | 1001 | 1200 | 10 | 食品 |
| 1 | 1002 | 980 | 8 | 日用品 |
| 2 | 1003 | error | 5 | 食品 |
| 3 | 1004 | 1500 | 12 | 家電 |
変換後のデータ型 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null int64 1 売上 4 non-null object 2 数量 4 non-null int64 3 カテゴリ 4 non-null object dtypes: int64(2), object(2) memory usage: 260.0+ bytes
数量 が object から int64 に変わります。 int は整数を表す型で、個数や件数のように小数を含まない値を扱うときによく使います。
このように、値がきれいに数字としてそろっている列では、astype(int) が素直に使いやすいです。
まず覚えたいのは、astype() は「変換先の型を自分で決めて変える」という点です。
変換前と変換後を見比べてみよう
見た目だけでは "10" と 10 の違いがわかりにくいことがあります。 そこで、数量 列の変換前と変換後を並べて確認してみます。
df_int_compare = df.copy()
print("変換前の数量列")
display(df_int_compare[["数量"]])
print("変換前のdtype:", df_int_compare["数量"].dtype)
df_int_compare["数量"] = df_int_compare["数量"].astype(int)
print("\n変換後の数量列")
display(df_int_compare[["数量"]])
print("変換後のdtype:", df_int_compare["数量"].dtype)
変換前の数量列
| 数量 | |
|---|---|
| 0 | 10 |
| 1 | 8 |
| 2 | 5 |
| 3 | 12 |
変換前のdtype: object 変換後の数量列
| 数量 | |
|---|---|
| 0 | 10 |
| 1 | 8 |
| 2 | 5 |
| 3 | 12 |
変換後のdtype: int64
よく使うパターン1:文字列に変換する
商品コードや会員番号のように、見た目は数字でも計算しない列は文字列にしておくと扱いやすいです。 先頭の0を残したいケースでも、文字列化が役立ちます。
df_str = df.copy()
df_str["商品コード"] = df_str["商品コード"].astype(str)
display(df_str)
print("\n変換後のデータ型")
df_str.info()
| 商品コード | 売上 | 数量 | カテゴリ | |
|---|---|---|---|---|
| 0 | 1001 | 1200 | 10 | 食品 |
| 1 | 1002 | 980 | 8 | 日用品 |
| 2 | 1003 | error | 5 | 食品 |
| 3 | 1004 | 1500 | 12 | 家電 |
変換後のデータ型 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null object 1 売上 4 non-null object 2 数量 4 non-null object 3 カテゴリ 4 non-null object dtypes: object(4) memory usage: 260.0+ bytes
商品コード が文字列型になります。 str は文字列を表す型で、商品コードや会員番号のように、計算せず識別のために使うデータでよく使います。
こうしておくと、あとで「001」「002」のような形式に整えたいときにも対応しやすいです。
計算する列は数値、識別のための列は文字列という考え方で整理すると、初心者でも迷いにくくなります。
文字列化の前後も確認してみよう
商品コードのような列は、見た目が数字でも計算より識別が目的です。 前後を比べると、値は似て見えても型の意味が変わることがわかります。
df_str_compare = df.copy()
print("変換前の商品コード列")
display(df_str_compare[["商品コード"]])
print("変換前のdtype:", df_str_compare["商品コード"].dtype)
df_str_compare["商品コード"] = df_str_compare["商品コード"].astype(str)
print("\n変換後の商品コード列")
display(df_str_compare[["商品コード"]])
print("変換後のdtype:", df_str_compare["商品コード"].dtype)
変換前の商品コード列
| 商品コード | |
|---|---|
| 0 | 1001 |
| 1 | 1002 |
| 2 | 1003 |
| 3 | 1004 |
変換前のdtype: int64 変換後の商品コード列
| 商品コード | |
|---|---|
| 0 | 1001 |
| 1 | 1002 |
| 2 | 1003 |
| 3 | 1004 |
変換後のdtype: object
astype(str) と astype("string") の違いも知っておこう
文字列化では astype(str) がよく使われますが、Pandas には astype("string") という書き方もあります。 どちらも文字列として扱えますが、欠損値の扱い方に少し違いがあります。
astype(str):値をPythonの文字列としてそろえるイメージastype("string"):Pandasの文字列型として扱うイメージ- 欠損値を含む列では、
astype("string")のほうが欠損を保ったまま扱いやすいことがあります
最初のうちは、欠損値がない列を単純に文字列化するなら astype(str)、 欠損値も含めて文字列列として丁寧に扱いたいなら astype("string") と考えると整理しやすいです。
df_string_compare = pd.DataFrame({
"商品コード": [1001, 1002, None, 1004]
})
df_string_compare["astype_str"] = df_string_compare["商品コード"].astype(str)
df_string_compare["astype_string"] = df_string_compare["商品コード"].astype("string")
print(df_string_compare)
print()
print(df_string_compare.dtypes)
商品コード astype_str astype_string 0 1001.0 1001.0 1001.0 1 1002.0 1002.0 1002.0 2 NaN nan <NA> 3 1004.0 1004.0 1004.0 商品コード float64 astype_str object astype_string string[python] dtype: object
上のように比べると、どちらも文字列列として使えますが、欠損値を含むと見え方や扱い方に差が出ることがあります。
初心者のうちは、次のように覚えておけば十分です。
- 識別コードをとりあえず文字列にしたい →
astype(str) - 欠損値も含めて文字列列として整えたい →
astype("string")
記事の主役は astype() そのものですが、この違いを知っておくと実務で迷いにくくなります。
よく使うパターン2:小数に変換する
売上や割合などで、小数も扱いたい場合は float に変換することがあります。 ただし、今回の 売上 列には "error" が含まれているので、そのままでは失敗します。
try:
df_float = df.copy()
df_float["売上"] = df_float["売上"].astype(float)
except Exception as e:
print("エラーが発生しました:")
print(e)
エラーが発生しました: could not convert string to float: 'error'
ここでエラーになるのは、"error" を float に変えられないためです。 astype() は便利ですが、変換できない値があると止まりやすいという特徴があります。
そのため、値が汚れている可能性がある列では、次に見る to_numeric() が役立ちます。
float は小数を表す数値型です。 売上や割合など、小数を含む可能性があるデータでよく使います。
ただし、今回のように文字が混ざっている列では、astype(float) をそのまま使うと失敗しやすいです。
よく使うパターン3:複数列をまとめて型変換する
列が増えてくると、1列ずつ書くのは少し手間です。 そんなときは、辞書の形で複数列の型をまとめて指定できます。
df_multi = df.copy()
# 売上は "error" があるので今回は数量と商品コードだけを変換
df_multi = df_multi.astype({
"商品コード": "str",
"数量": "int"
})
display(df_multi)
print("\n変換後のデータ型")
df_multi.info()
| 商品コード | 売上 | 数量 | カテゴリ | |
|---|---|---|---|---|
| 0 | 1001 | 1200 | 10 | 食品 |
| 1 | 1002 | 980 | 8 | 日用品 |
| 2 | 1003 | error | 5 | 食品 |
| 3 | 1004 | 1500 | 12 | 家電 |
変換後のデータ型 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null object 1 売上 4 non-null object 2 数量 4 non-null int64 3 カテゴリ 4 non-null object dtypes: int64(1), object(3) memory usage: 260.0+ bytes
複数列を一度に整えられるので、前処理の見通しがよくなります。 ただし、1つでも変換できない列が含まれるとエラーになりやすいため、列ごとに状態を確認してから使うのがおすすめです。
astype() と to_numeric() の違い
初心者が迷いやすいのが、astype() と pd.to_numeric() の使い分けです。
astype() が向いている場面
- 変換先の型を自分ではっきり決めたい
- 値がすでにきれいにそろっている
- 1列または複数列を明示的に整えたい
to_numeric() が向いている場面
- 数値に変えたいが、文字や記号が混ざっているかもしれない
- 変換できない値を
NaNにしたい - まず数値化できるものだけ安全に変換したい
つまり、きれいな列には astype()、汚れた列には to_numeric() を検討すると考えると整理しやすいです。
df_numeric = df.copy()
df_numeric["売上"] = pd.to_numeric(df_numeric["売上"], errors="coerce")
display(df_numeric)
print("\n変換後のデータ型")
df_numeric.info()
| 商品コード | 売上 | 数量 | カテゴリ | |
|---|---|---|---|---|
| 0 | 1001 | 1200.0 | 10 | 食品 |
| 1 | 1002 | 980.0 | 8 | 日用品 |
| 2 | 1003 | NaN | 5 | 食品 |
| 3 | 1004 | 1500.0 | 12 | 家電 |
変換後のデータ型 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null int64 1 売上 3 non-null float64 2 数量 4 non-null object 3 カテゴリ 4 non-null object dtypes: float64(1), int64(1), object(2) memory usage: 260.0+ bytes
"error" は数値に変換できないため、NaN になります。 これで列全体は数値として扱いやすくなります。
この流れは、実務でもよくあります。 まず数値にできるものだけ数値にして、変換できなかった値は欠損として扱うイメージです。
そのあとで fillna() や dropna() を使って整えていくと、前処理が進めやすくなります。
to_numeric() の前後比較も見てみよう
astype() では止まってしまう列でも、pd.to_numeric(errors="coerce") を使うと、変換できない値だけを NaN にできます。 前後を見比べると、どこが変わったのか把握しやすくなります。
df_numeric_compare = df.copy()
print("変換前の売上列")
display(df_numeric_compare[["売上"]])
print("変換前のdtype:", df_numeric_compare["売上"].dtype)
df_numeric_compare["売上"] = pd.to_numeric(df_numeric_compare["売上"], errors="coerce")
print("\n変換後の売上列")
display(df_numeric_compare[["売上"]])
print("変換後のdtype:", df_numeric_compare["売上"].dtype)
変換前の売上列
| 売上 | |
|---|---|
| 0 | 1200 |
| 1 | 980 |
| 2 | error |
| 3 | 1500 |
変換前のdtype: object 変換後の売上列
| 売上 | |
|---|---|
| 0 | 1200.0 |
| 1 | 980.0 |
| 2 | NaN |
| 3 | 1500.0 |
変換後のdtype: float64
失敗しやすい変換と安全な変換を並べて整理しよう
ここまでの内容をまとめると、初心者が迷いやすいポイントは次の通りです。
| 状況 | 向いている方法 | 理由 |
|---|---|---|
| 値がきれいにそろっている | astype() | 型を自分で明示的に決めやすい |
| 数字に見えても文字や記号が混ざるかもしれない | pd.to_numeric() | 変換できない値を NaN にして確認しやすい |
| 識別コードを文字列として扱いたい | astype(str) | 先頭0やコード列を文字列として扱いやすい |
| 欠損値も含めて文字列列に整えたい | astype("string") | 欠損を含む文字列列として扱いやすい |
このように、「明示的に型を決めるか」「安全に変換したいか」で考えると、使い分けがかなり整理しやすくなります。
convert_dtypes() と infer_objects() との違い
astype() の比較対象として、convert_dtypes() と infer_objects() も知っておくと整理しやすいです。
convert_dtypes()
- DataFrame全体の型を、できる範囲で自動的により適切な型へ寄せる
- 「まず全体を整えたい」ときに便利
- ただし、この列を必ず int にしたいのような明示性は弱めです
infer_objects()
object型の列について、より適切な型へ推測して変換を試みる- 補助的な場面では便利
- ただし初心者にとっては、まず
astype()とto_numeric()を押さえるほうが実用的です
この記事では、主役を astype() に絞ります。 迷ったら、自分で型を決めたいときは astype()、安全に数値化したいときは to_numeric() と覚えておくと使いやすいです。
df_auto = df.copy()
print("convert_dtypes() を使う前")
df_auto.info()
df_auto = df_auto.convert_dtypes()
print("\nconvert_dtypes() を使った後")
df_auto.info()
convert_dtypes() を使う前 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null int64 1 売上 4 non-null object 2 数量 4 non-null object 3 カテゴリ 4 non-null object dtypes: int64(1), object(3) memory usage: 260.0+ bytes convert_dtypes() を使った後 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 商品コード 4 non-null Int64 1 売上 4 non-null string 2 数量 4 non-null string 3 カテゴリ 4 non-null string dtypes: Int64(1), string(3) memory usage: 264.0 bytes
convert_dtypes() は便利ですが、自分で細かく指定するというより、DataFrame全体を自動で整える補助役という位置づけです。 初心者が「この列を今すぐ文字列や数値に変えたい」と思ったときは、まず astype() を中心に覚えるほうがわかりやすいです。
pandas astype() でよくあるエラーと注意点
astype() は便利ですが、次のような場面ではつまずきやすいです。
1. 数字に見えても、文字が混ざっている
今回の 売上 列の "error" のように、1つでも数値でない値があると、astype(int) や astype(float) は失敗しやすいです。
対処の考え方
- 値がきれいにそろっているなら
astype() - 混ざりものがありそうなら
pd.to_numeric(errors="coerce")
2. 欠損値がある列に整数変換しようとして失敗することがある
欠損値があると、整数型への変換で迷う場面があります。 初心者のうちは、まず float で扱うか、fillna() で補ってから考えると進めやすいです。
df_missing = pd.DataFrame({
"数量": ["10", None, "5", "12"]
})
print("元のDataFrame")
display(df_missing)
df_missing["数量_numeric"] = pd.to_numeric(df_missing["数量"], errors="coerce")
print("\n数値化した後")
display(df_missing)
print("\nデータ型")
df_missing.info()
元のDataFrame
| 数量 | |
|---|---|
| 0 | 10 |
| 1 | None |
| 2 | 5 |
| 3 | 12 |
数値化した後
| 数量 | 数量_numeric | |
|---|---|---|
| 0 | 10 | 10.0 |
| 1 | None | NaN |
| 2 | 5 | 5.0 |
| 3 | 12 | 12.0 |
データ型 <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 数量 3 non-null object 1 数量_numeric 3 non-null float64 dtypes: float64(1), object(1) memory usage: 196.0+ bytes
None は数値化すると欠損値になります。 このような列は、まず欠損を確認してから、必要に応じて fillna() で補う流れが自然です。
3. 代入し忘れると元の列は変わらない
astype() は、次のように結果を代入して使うことが多いです。
df["数量"] = df["数量"].astype(int)
df["数量"].astype(int) と書いただけでは、元のDataFrameが変わらないことがあります。 ここも、初心者が見落としやすい点です。
実務やデータ分析ではどう役立つか
astype() は、単なる型変換の知識ではありません。 データ分析の流れの中では、次のような場面で役立ちます。
1. head() や info() で全体像を確認する 2. 数値なのに object になっている列を見つける 3. astype() や to_numeric() で型を整える 4. 欠損が出たら isnull() や fillna() で対応する 5. そのあとに集計や可視化へ進む
この順番で考えると、astype() は抽出や集計の前段階にある前処理の基本操作だとわかります。
たとえば、売上列が文字列のままだと、平均・合計・グラフ化がやりにくくなります。 先に型を整えておくことで、その後の groupby() や可視化もスムーズになります。
関連する前処理もあわせて押さえると理解しやすい
astype() は単体で覚えるより、前後の操作とセットで理解すると定着しやすいです。
- CSV読込直後の列の型確認 →
read_csv()/info() - 数値化できない値の洗い出し →
pd.to_numeric() - 数値化した結果できた欠損値の確認 →
isnull() - 欠損値への対応 →
fillna()
この流れで見ると、astype() は前処理の中継点のような役割を持っています。 単なる文法としてではなく、「次の集計や可視化を正しく行うための準備」として覚えておくと使いやすくなります。
また、実際の作業では astype() だけを単独で使うことはあまりありません。 たとえば、CSVを読み込んだ直後は read_csv() や info() で列の状態を確認し、必要に応じて to_numeric() や fillna() につなげる流れになることが多いです。
この流れを意識しておくと、astype() を「型変換の単発テクニック」ではなく、 前処理全体の中でどこに位置づくかまで理解しやすくなります。
まとめ
pandas astype() は、列やDataFrameの型を明示的に変えるための基本機能です。
今回のポイントを整理すると、次のようになります。
astype()は、型を自分で決めて変えたいときに使いやすい- 文字列・整数・小数への変換でよく使う
- 値がきれいにそろっている列では特に使いやすい
- 文字やエラー値が混ざっている列では、そのまま使うと失敗しやすい
- 汚れた列を数値化したいときは
pd.to_numeric(errors="coerce")が便利 - 型変換は、データ分析の前処理としてとても重要
迷ったら、まず info() で型を確認し、 きれいな列には astype()、不安な列には to_numeric() という考え方から始めるのがおすすめです。
内部リンク
- Pandas DataFrame入門|作り方・基本操作をわかりやすく解説
- Pandas info()とdescribe()の違い|欠損値・型・統計量の見方を例で解説
- pandas fillna()の使い方|欠損値を0・平均値・中央値・最頻値で埋める方法を初心者向けに解説
- 欠損値を可視化して攻略!Pandas isnullとヒートマップ活用術
- Google Colab CSV 読み込み&保存入門|pandas で read_csv と to_csv を徹底解説
型変換は単独で終わる知識ではなく、
データ確認 → 前処理 → 集計・可視化 という流れの中で理解するとつながりやすいです。
Q1. pandas astype() で文字列に変換すると何が便利ですか?
商品コードや会員番号のように、計算しない列を文字列としてそろえやすくなります。
識別用の列を数値のままにしておくと、意図しない扱いになることがあるため、文字列化が役立つことがあります。
Q2. astype(int) でエラーになるのはなぜですか?
列の中に文字列や記号、欠損値など、整数に変換できない値が混ざっていることが多いです。
まずは pd.to_numeric(errors="coerce") で確認すると、原因を見つけやすくなります。
Q3. astype() と to_numeric() はどちらを覚えればよいですか?
最初は両方の役割をざっくり分けて覚えるのがおすすめです。
型を自分で指定して変えたいなら astype()、安全に数値化したいなら to_numeric() と考えると使いやすいです。
Q4. astype() はDataFrame全体にも使えますか?
使えます。
ただし、複数列のうち1つでも変換できない列があるとエラーになりやすいので、列ごとの状態を確認しながら進めると安心です。
コメント