pandas の astype() は、DataFrameやSeriesのデータ型を変換するメソッドです。
たとえば、文字列として読み込まれた数値を整数や小数に変換したり、数値を文字列に変換したりできます。
df["売上"] = df["売上"].astype(int)
df["商品コード"] = df["商品コード"].astype(str)
CSVを読み込んだあと、数値のはずの列が文字列になっていると、集計や計算がうまくできないことがあります。
そのようなときに使うのが astype() です。
この記事では、astype() の基本、astype(str)、astype(int)、astype(float)、astype("string")、欠損値を含む整数変換、複数列の型変換、to_numeric() との違い、よくあるエラー対処まで、初心者向けに出力例つきで解説します。
この記事でわかること
astype()の意味df.dtypesで現在のデータ型を確認する方法astype()は代入しないと元データが変わらないことastype(str)とastype("string")の違いastype(int)、astype(float)で数値型に変換する方法- 小数を
astype(int)にすると切り捨てられること - 欠損値を含む整数列を
Int64に変換する方法 - 複数列をまとめて型変換する方法
astype()とto_numeric()、convert_dtypes()の違いastype()でよくあるエラーと対処法
pandas astype()とは?列のデータ型を変換するメソッド
astype() は、DataFrameやSeriesのデータ型を指定した型に変換するメソッドです。
基本形は次のとおりです。
df["列名"].astype(変換したい型)
たとえば、"100" のような文字列を整数にしたい場合は、astype(int) を使います。
最初に覚えるなら、次の表で十分です。
| やりたいこと | 書き方 |
|---|---|
| 文字列に変換 | astype(str) |
| pandasの文字列型に変換 | astype("string") |
| 整数に変換 | astype(int) |
| 欠損値を含む整数に変換 | astype("Int64") |
| 小数に変換 | astype(float) |
| 複数列をまとめて変換 | df.astype({"列1": int, "列2": float}) |
サンプルデータを用意する
ここでは、CSVを読み込んだあとによく起きる状況を想定します。
- 数値のように見えるが文字列になっている列
- 欠損値を含む列
- 文字列として扱いたい商品コード
- 変換に失敗しやすい値を含む列
を含むDataFrameを作成します。
import pandas as pd
import numpy as np
df = pd.DataFrame({
"商品コード": [1001, 1002, 1003, 1004, 1005],
"商品": ["ノートPC", "マウス", "キーボード", "モニター", "USBメモリ"],
"売上": ["120000", "15000", "24000", "64000", "25000"],
"数量": ["1", "5", "3", "2", "10"],
"割引率": ["0.10", "0.05", "0.00", "0.15", "0.08"],
"在庫": ["12", "8", None, "5", "20"],
"備考": ["通常", "通常", "確認中", None, "通常"]
})
df
| 商品コード | 商品 | 売上 | 数量 | 割引率 | 在庫 | 備考 | |
|---|---|---|---|---|---|---|---|
| 0 | 1001 | ノートPC | 120000 | 1 | 0.10 | 12 | 通常 |
| 1 | 1002 | マウス | 15000 | 5 | 0.05 | 8 | 通常 |
| 2 | 1003 | キーボード | 24000 | 3 | 0.00 | NaN | 確認中 |
| 3 | 1004 | モニター | 64000 | 2 | 0.15 | 5 | NaN |
| 4 | 1005 | USBメモリ | 25000 | 10 | 0.08 | 20 | 通常 |
このDataFrameでは、売上、数量、割引率、在庫 が数値のように見えます。
しかし、実際のデータ型はどうなっているでしょうか。
型変換の前にdtypesで現在のデータ型を確認する
型変換をする前に、まず dtypes で各列のデータ型を確認します。
df.dtypes
| 商品コード | int64 |
| 商品 | object |
| 売上 | object |
| 数量 | object |
| 割引率 | object |
| 在庫 | object |
| 備考 | object |
object は、文字列や混在データが入っているときによく表示されます。
今回の例では、売上 や 数量 は数値のように見えますが、実際には文字列として扱われています。
型変換の基本手順は次のとおりです。
df.dtypesで現在の型を確認するastype()で型を変換する- もう一度
df.dtypesで変換後を確認する
astype()の基本的な使い方
ここで重要なのは、astype() は変換後のSeriesやDataFrameを返すメソッドだという点です。
そのため、元の列を変換したい場合は、次のように代入します。
df["売上"] = df["売上"].astype(int)
一方、次のように書くだけでは、変換結果を表示するだけで、元のDataFrameには反映されません。
df["売上"].astype(int)
まず、売上 列を整数に変換します。
売上 列は文字列として入っていますが、すべて数字だけなので astype(int) で変換できます。
代入しないと元データは変わらない
astype() の結果を確認するために、まず小さなSeriesで試してみます。
s = pd.Series(["1", "2", "3"])
s.astype(int)
| 0 | 1 |
| 1 | 2 |
| 2 | 3 |
この時点では、astype(int) の結果は表示されています。
しかし、元の s 自体はまだ文字列のままです。
s.dtype
object
元データを変換後の型にしたい場合は、次のように代入します。
s = s.astype(int)
s.dtype
int64
df["売上"] = df["売上"].astype(int)
df.dtypes
| 商品コード | int64 |
| 商品 | object |
| 売上 | int64 |
| 数量 | object |
| 割引率 | object |
| 在庫 | object |
| 備考 | object |
売上 列が整数型に変わりました。
実際にデータも確認します。
df.head()
| 商品コード | 商品 | 売上 | 数量 | 割引率 | 在庫 | 備考 | |
|---|---|---|---|---|---|---|---|
| 0 | 1001 | ノートPC | 120000 | 1 | 0.10 | 12 | 通常 |
| 1 | 1002 | マウス | 15000 | 5 | 0.05 | 8 | 通常 |
| 2 | 1003 | キーボード | 24000 | 3 | 0.00 | NaN | 確認中 |
| 3 | 1004 | モニター | 64000 | 2 | 0.15 | 5 | NaN |
| 4 | 1005 | USBメモリ | 25000 | 10 | 0.08 | 20 | 通常 |
見た目は大きく変わらないこともあります。
しかし、データ型が整数になったため、合計や平均などの計算ができるようになります。
df["売上"].sum()
248000
astype() は、見た目を変えるというより、計算や集計に使える型に変えるための処理です。
文字列に変換する
astype(str) と astype("string") の違いを整理します。文字列列に欠損値がある場合は、どちらを使うかで扱いが変わります。
astype(str)で文字列に変換する
数値を文字列として扱いたい場合は、astype(str) を使います。
たとえば、商品コードは数値計算に使うというより、IDとして扱うことが多いです。 そのような列は、文字列にしておくとわかりやすくなります。
df["商品コード_str"] = df["商品コード"].astype(str)
df[["商品コード", "商品コード_str"]]
| 商品コード | 商品コード_str | |
|---|---|---|
| 0 | 1001 | 1001 |
| 1 | 1002 | 1002 |
| 2 | 1003 | 1003 |
| 3 | 1004 | 1004 |
| 4 | 1005 | 1005 |
変換後の型を確認します。
df[["商品コード", "商品コード_str"]].dtypes
| 商品コード | int64 |
| 商品コード_str | object |
商品コード_str は文字列として扱われます。
ただし、astype(str) には注意点があります。
欠損値がある列に astype(str) を使うと、欠損値が文字列の "None" や "nan" のように変換されることがあります。
astype(str)とastype(“string”)の違い
pandasでは、文字列変換に astype(str) と astype("string") の2つの書き方があります。
違いを確認するために、欠損値を含む 備考 列で試してみます。
df["備考_str"] = df["備考"].astype(str)
df["備考_string"] = df["備考"].astype("string")
df[["備考", "備考_str", "備考_string"]]
| 備考 | 備考_str | 備考_string | |
|---|---|---|---|
| 0 | 通常 | 通常 | 通常 |
| 1 | 通常 | 通常 | 通常 |
| 2 | 確認中 | 確認中 | 確認中 |
| 3 | NaN | None | NaN |
| 4 | 通常 | 通常 | 通常 |
型を確認します。
df[["備考_str", "備考_string"]].dtypes
| 備考_str | object |
| 備考_string | string |
大まかには、次のように考えるとわかりやすいです。
| 書き方 | 特徴 |
|---|---|
astype(str) |
Pythonの文字列に変換する。欠損値も文字列化されやすい |
astype("string") |
pandasの文字列型に変換する。欠損値を扱いやすい |
初心者には、欠損値を含む文字列列では astype("string") の方が安全です。
ただし、単純に表示用として文字列化したいだけなら astype(str) でもよく使われます。
数値型に変換する
astype(int)、astype(float)、小数を整数に変換するときの注意点をまとめます。
astype(int)で整数に変換する
数字だけが入っている文字列列は、astype(int) で整数に変換できます。
ここでは、数量 列を整数に変換します。
なお、小数を astype(int) で整数に変換すると、小数点以下は切り捨てられます。
四捨五入したい場合は、先に round() などで丸めてから astype(int) を使います。
df["数量"] = df["数量"].astype(int)
df[["数量"]].dtypes
| 数量 | int64 |
整数に変換すると、合計や平均を計算できます。
df["数量"].sum()
21
astype(int) は便利ですが、列に欠損値や数字以外の文字が含まれているとエラーになります。
その場合は、後で説明する astype("Int64") や to_numeric() を使う方が安全です。
小数をastype(int)にすると切り捨てられる
astype(int) は、小数を整数に変換するときにも使えます。
ただし、小数点以下は四捨五入ではなく、切り捨てられます。
s_float = pd.Series([1.2, 2.8, 3.5])
s_float.astype(int)
| 0 | 1 |
| 1 | 2 |
| 2 | 3 |
四捨五入してから整数にしたい場合は、先に round() を使います。
s_float.round().astype(int)
| 0 | 1 |
| 1 | 3 |
| 2 | 4 |
このように、astype(int) は型を整数に変えるだけで、四捨五入の処理を自動で行うわけではありません。
小数点以下をどう扱いたいかを考えてから変換しましょう。
astype(float)で小数に変換する
小数として扱いたい列は、astype(float) を使います。
ここでは、割引率 列を小数に変換します。
df["割引率"] = df["割引率"].astype(float)
df[["割引率"]].dtypes
| 割引率 | float64 |
df[["商品", "割引率"]]
| 商品 | 割引率 | |
|---|---|---|
| 0 | ノートPC | 0.1 |
| 1 | マウス | 0.05 |
| 2 | キーボード | 0 |
| 3 | モニター | 0.15 |
| 4 | USBメモリ | 0.08 |
割引率 のように小数を含む列は、float 型にしておくと計算しやすくなります。
欠損値を含む列の型変換
欠損値がある列では、通常の int や str 変換でつまずくことがあります。ここでは、欠損値を含む列で注意すべき型変換を整理します。
欠損値を含む整数列はastype(“Int64”)を使う
欠損値を含む列を通常の astype(int) で整数に変換しようとすると、エラーになることがあります。
たとえば、在庫 列には欠損値が含まれています。
なお、欠損値を 0 や平均値などで埋めてから型変換したい場合は、fillna() の領域です。
この記事では、astype() の観点から 欠損値を含む整数列は Int64 を使う ところまでを中心に扱います。
※ 欠損値を埋める fillna() については、別記事で解説予定です。
df[["在庫"]]
| 在庫 | |
|---|---|
| 0 | 12 |
| 1 | 8 |
| 2 | NaN |
| 3 | 5 |
| 4 | 20 |
このような列を欠損値を保ったまま整数として扱いたい場合は、pandasの nullable integer 型である Int64 を使います。
まず、在庫 列を数値に変換してから、Int64 にします。
df["在庫"] = pd.to_numeric(df["在庫"], errors="coerce").astype("Int64")
df[["在庫"]]
| 在庫 | |
|---|---|
| 0 | 12 |
| 1 | 8 |
| 2 | NaN |
| 3 | 5 |
| 4 | 20 |
df[["在庫"]].dtypes
| 在庫 | Int64 |
Int64 は、欠損値を含む整数列を扱いたいときに便利です。
| 型 | 欠損値を含む整数列 |
|---|---|
int |
欠損値があるとエラーになりやすい |
"Int64" |
欠損値を含んだまま整数として扱える |
列に欠損値がありそうな場合は、astype(int) より astype("Int64") を検討するとよいです。
astype(str)で欠損値まで文字列になる注意点
欠損値を含む列に astype(str) を使うと、欠損値が "None" や "nan" のような文字列として扱われることがあります。
欠損値を欠損値のまま扱いたい文字列列では、astype("string") を検討するとよいです。
複数列をまとめて型変換する
複数列を一度に型変換したい場合は、辞書で列名と型を指定します。
df.astype({"列1": 型1, "列2": 型2})
ここでは、例として新しいDataFrameを作り直して、複数列をまとめて変換します。
df2 = pd.DataFrame({
"売上": ["120000", "15000", "24000"],
"数量": ["1", "5", "3"],
"割引率": ["0.10", "0.05", "0.00"]
})
df2 = df2.astype({
"売上": int,
"数量": int,
"割引率": float
})
df2.dtypes
| 売上 | int64 |
| 数量 | int64 |
| 割引率 | float64 |
df2
| 売上 | 数量 | 割引率 | |
|---|---|---|---|
| 0 | 120000 | 1 | 0.1 |
| 1 | 15000 | 5 | 0.05 |
| 2 | 24000 | 3 | 0 |
複数列の型をまとめて変えたい場合は、astype() に辞書を渡すと読みやすくなります。
astype()と関連メソッドの違い
astype() と混同しやすい to_numeric()、convert_dtypes() との違いを整理します。この記事では、これらは補足として扱います。
astype()とto_numeric()の違い
astype() と似た用途で使われるのが pd.to_numeric() です。
ただし、この2つは主役が違います。
| メソッド | 主な役割 | 向いている場面 |
|---|---|---|
astype() |
型を明示的に指定して変換する | 変換できることが分かっている列を、指定した型に変える |
to_numeric() |
数値に変換できるかを安全に試す | 数字以外の値が混ざっている可能性がある列を数値化する |
たとえば、列の中に "不明" や "-" などが混ざっている場合、astype(int) ではエラーになることがあります。
そのようなときは、pd.to_numeric(errors="coerce") を使うと、変換できない値を NaN にできます。
s = pd.Series(["100", "200", "不明", "300"])
pd.to_numeric(s, errors="coerce")
| 0 | 100 |
| 1 | 200 |
| 2 | NaN |
| 3 | 300 |
この記事では、to_numeric() は astype() で変換できない値がある場合の補助 として扱います。
to_numeric() 自体を詳しく知りたい場合は、別記事で確認するのがよいです。
※ to_numeric() の詳しい使い方は、別記事で解説予定です。
astype()とconvert_dtypes()の違い
convert_dtypes() は、DataFrame全体の列を、pandasが扱いやすい型に自動変換するメソッドです。
astype() とは目的が少し違います。
| メソッド | 主な役割 |
|---|---|
astype() |
自分で型を指定して変換する |
convert_dtypes() |
DataFrame全体をpandas向けの型に自動で整える |
この記事の主役は、列ごとに型を明示して変換する astype() です。
一方、DataFrame全体の型をまとめて自動で整えたい場合は、convert_dtypes() が候補になります。
※ convert_dtypes() の詳しい使い方は、別記事で解説予定です。
astype()でよくあるエラーと対処法
ここでは、astype() でよくあるエラーを整理します。
ValueError:数字以外の文字が混ざっている
数字に変換したい列に、数字以外の文字が混ざっているとエラーになります。
s = pd.Series(["10", "20", "不明", "40"])
try:
s.astype(int)
except ValueError as e:
print(type(e).__name__)
print(e)
ValueError
invalid literal for int() with base 10: '不明'
この場合は、pd.to_numeric() を使って、変換できない値を NaN にする方法があります。
pd.to_numeric(s, errors="coerce")
| 0 | 10 |
| 1 | 20 |
| 2 | NaN |
| 3 | 40 |
欠損値がある列をintに変換しようとしてエラーになる
欠損値を含む列を通常の int に変換すると、エラーになることがあります。
s = pd.Series(["1", "2", None, "4"])
try:
s.astype(int)
except TypeError as e:
print(type(e).__name__)
print(e)
except ValueError as e:
print(type(e).__name__)
print(e)
TypeError
int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
欠損値を含む整数列にしたい場合は、pd.to_numeric() と astype("Int64") を組み合わせます。
pd.to_numeric(s, errors="coerce").astype("Int64")
| 0 | 1 |
| 1 | 2 |
| 2 | NaN |
| 3 | 4 |
astype(str)で欠損値まで文字列になってしまう
欠損値を含む列に astype(str) を使うと、欠損値が文字列の "None" や "nan" のようになることがあります。
欠損値を保ったまま文字列として扱いたい場合は、astype("string") を検討します。
s = pd.Series(["A", None, "C"])
pd.DataFrame({
"元データ": s,
"astype(str)": s.astype(str),
'astype("string")': s.astype("string")
})
| 元データ | astype(str) | astype("string") | |
|---|---|---|---|
| 0 | A | A | A |
| 1 | NaN | None | NaN |
| 2 | C | C | C |
astype()を使っても元データが変わらない
astype() は変換後のデータを返すメソッドです。
元の列を変換したい場合は、次のように代入します。
df["列"] = df["列"].astype(...)
代入しないと、変換結果を表示しただけで、元のDataFrameには反映されません。
実務でのおすすめ手順
CSVやExcelを読み込んだあと、型変換で迷ったら、次の順番で確認すると安全です。
df.head()
df.dtypes
df.info()
そのうえで、列の状態に応じて変換します。
| 状態 | おすすめ |
|---|---|
| 数字だけの文字列 | astype(int) または astype(float) |
| 文字列として扱いたいID・コード | astype(str) または astype("string") |
| 欠損値を含む整数列 | pd.to_numeric(...).astype("Int64") |
| 数字以外の値が混ざる | pd.to_numeric(errors="coerce") |
| 複数列をまとめて変えたい | df.astype({"列名": 型}) |
| 変換結果を元の列に反映したい | df["列"] = df["列"].astype(...) |
| 小数を整数にしたい | 必要なら先に round() してから astype(int) |
| DataFrame全体を自動で整えたい | convert_dtypes() |
| 欠損値を埋めてから変換したい | fillna() |
この記事では、主に astype() による明示的な型変換を扱いました。
to_numeric()、convert_dtypes()、fillna() は、必要に応じて内部リンク先の記事で詳しく確認するとよいです。
まとめ
この記事では、pandas の astype() の使い方を解説しました。
重要なポイントは次のとおりです。
| 書き方 | 意味 |
|---|---|
df["列"].astype(str) |
文字列に変換 |
df["列"].astype("string") |
pandasの文字列型に変換 |
df["列"].astype(int) |
整数に変換 |
df["列"].astype("Int64") |
欠損値を含む整数に変換 |
df["列"].astype(float) |
小数に変換 |
df.astype({"列1": int, "列2": float}) |
複数列をまとめて型変換 |
df["列"] = df["列"].astype(...) |
変換結果を元の列に反映 |
pd.to_numeric(..., errors="coerce") |
変換できない値をNaNにして数値化 |
convert_dtypes() |
DataFrame全体をpandas向けの型に自動変換 |
astype() は、列のデータ型を明示的に変えるための基本メソッドです。
ただし、欠損値や数字以外の文字が混ざっている列ではエラーになりやすいため、to_numeric() や Int64 との使い分けも覚えておくと安心です。
この記事の主役は、型を自分で指定して変換する astype() です。
to_numeric()、convert_dtypes()、fillna() は関連機能ですが、役割は異なります。
| 関連機能 | 役割 |
|---|---|
to_numeric() |
文字列を安全に数値化する |
convert_dtypes() |
DataFrame全体の型を自動で整える |
fillna() |
欠損値を埋める |
astype() 記事では、これらを深掘りしすぎず、必要な場面で使い分けることが重要です。
また、次の2点は初心者がつまずきやすい重要ポイントです。
astype()は変換後のデータを返すため、元の列を変えたい場合は代入が必要- 小数を
astype(int)で整数にすると、小数点以下は切り捨てられる
この2点を押さえておくと、型変換のミスを減らせます。
次に読みたい関連記事
- Pandas DataFrame入門|作り方・基本操作をわかりやすく解説
- pandas head()の使い方|df.head()で先頭5行を表示・tail()との違いも解説
- pandas describe()の使い方|統計量の意味・include=’all’・info()との違いを解説
- pandas value_counts()の使い方|件数集計・割合表示・欠損値の数え方を解説
- Google ColabでCSVを読み込む方法|Drive連携とpandas read_csvを初心者向けに解説
公式ドキュメント
詳しい仕様を確認したい場合は、pandas公式ドキュメントも参考になります。
pandasのastype()は何をするメソッドですか?
astype() は、DataFrameやSeriesのデータ型を変換するメソッドです。文字列を整数や小数に変換したり、数値を文字列に変換したりできます。
astype(str)とastype(“string”)の違いは何ですか?
astype(str) はPythonの文字列に変換します。一方、astype("string") はpandasの文字列型に変換します。欠損値を含む列では、astype("string") の方が扱いやすいことがあります。
astype(int)でエラーになるのはなぜですか?
列に欠損値や数字以外の文字が含まれていると、astype(int) でエラーになることがあります。その場合は、pd.to_numeric(errors="coerce") や astype("Int64") を使うと安全です。
欠損値を含む整数列はどう変換すればよいですか?
欠損値を含む整数列は、pandasの nullable integer 型である Int64 を使います。たとえば、pd.to_numeric(s, errors="coerce").astype("Int64") のように書きます。
astype()とto_numeric()はどう使い分けますか?
変換できることが分かっている列は astype()、数字以外の文字が混ざっている可能性がある列は to_numeric() が向いています。to_numeric(errors="coerce") を使うと、変換できない値を NaN にできます。to_numeric()の詳しい使い方は、専用記事で確認するとよいです。
複数列をまとめて型変換できますか?
はい。df.astype({"売上": int, "割引率": float}) のように、辞書で列名と型を指定すると、複数列をまとめて型変換できます。
astype()を使ったのに元のDataFrameが変わらないのはなぜですか?
astype() は、変換後のSeriesやDataFrameを返すメソッドです。元の列を変換したい場合は、df["列"] = df["列"].astype(...) のように代入する必要があります。
小数をastype(int)で整数にすると四捨五入されますか?
いいえ。astype(int) で小数を整数にすると、小数点以下は切り捨てられます。四捨五入したい場合は、先に round() などで丸めてから astype(int) を使います。
コメント