🔍 ステップ28: データ型の変換(astype)
データの「型」を理解して、正しく変換できるようになろう!
ステップ27では、欠損値の処理方法を学びました。今回は、データ型の変換を学びます。データには「整数」「小数」「文字列」などの型があり、正しい型に変換することで計算や分析が可能になります。
📖 このステップで学ぶこと
・データ型とは何か、なぜ大切なのか
・dtypesでデータ型を確認する方法
・astype()でデータ型を変換する
・pd.to_numeric()でエラーに対処する
・pd.to_datetime()で日付型に変換する
・複数列を一括で変換する
学習時間の目安: 2〜2.5時間
🎯 1. データ型とは?
データには型(かた)があります。同じ「100」という値でも、数値の100と文字列の”100″は全く違うものとして扱われます。
🔰 なぜデータ型が大切なのか?
データ型を理解することは、データ分析の基本です。型が違うと、同じ操作でも結果が全く異なります。
💡 データ型が違うと何が起きる?
数値の100 + 200 = 300(足し算ができる)
文字列の”100″ + “200” = “100200”(文字が連結される!)
このように、見た目は同じ「100」でも、型が違うと結果が全く異なります。
CSVファイルを読み込んだ時、数値が文字列として読み込まれることがよくあります。そのままでは計算ができないので、正しい型に変換する必要があります。
📊 Pandasの主なデータ型
Pandasで使用する主なデータ型を確認しましょう。
📌 データ型一覧
| データ型 | 説明 | 例 |
| int64 | 整数(小数点なし) | 1, 100, -5, 0 |
| float64 | 小数(浮動小数点数) | 3.14, 100.0, -2.5 |
| object | 文字列 | “りんご”, “100”, “ABC” |
| bool | 真偽値 | True, False |
| datetime64 | 日付・時刻 | 2024-01-01, 2024-01-15 10:30:00 |
objectは「文字列」を意味します。数値のように見えても、objectと表示されていたら文字列として扱われています。
📝 データ型を確認する方法
DataFrameの各列のデータ型を確認するには、dtypes属性を使います。「d」はdata、「types」は型の複数形で、「データの型たち」という意味です。
📝 dtypesの書き方
df.dtypes
・DataFrameの全ての列のデータ型を一覧で表示します
コード:データ型を確認する
# Pandasをインポート
import pandas as pd
# サンプルデータを作成
data = {
'商品名': ['りんご', 'バナナ', 'みかん'],
'価格': [100, 150, 80],
'在庫': [50, 30, 45],
'評価': [4.5, 4.8, 4.2]
}
df = pd.DataFrame(data)
print("データ:")
print(df)
print()
# 各列のデータ型を確認
print("各列のデータ型:")
print(df.dtypes)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: 商品名 価格 在庫 評価 0 りんご 100 50 4.5 1 バナナ 150 30 4.8 2 みかん 80 45 4.2 各列のデータ型: 商品名 object 価格 int64 在庫 int64 評価 float64 dtype: object
💡 結果の読み方
商品名: object → 文字列(りんご、バナナなど)
価格: int64 → 整数(100、150など、小数点がない数値)
在庫: int64 → 整数
評価: float64 → 小数(4.5、4.8など、小数点がある数値)
Pandasは自動的に適切な型を判断してくれます。ただし、CSVファイルを読み込んだ時などに意図しない型になることがあるので、必ず確認する習慣をつけましょう。
🔀 2. astype()でデータ型を変換
astype()は、データ型を変換するメソッドです。「as type(〜の型として)」という意味で、指定した型に変換します。
🔰 文字列を数値に変換する
CSVファイルを読み込むと、数値が文字列として認識されることがあります。計算するには数値型に変換が必要です。
📝 astype()の書き方
df[‘列名’].astype(型)
・astype(int):整数に変換
・astype(float):小数に変換
・astype(str):文字列に変換
・元のデータは変更されず、新しいデータが返されます
まず、文字列として格納されたデータを確認してみましょう。
コード:文字列データを確認
import pandas as pd
# 文字列として格納された数値データ
# シングルクォート('')で囲まれているので文字列
data = {
'商品ID': ['001', '002', '003'],
'価格': ['100', '200', '150'],
'数量': ['10', '5', '8']
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print()
print("データ型:")
print(df.dtypes)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 商品ID 価格 数量 0 001 100 10 1 002 200 5 2 003 150 8 データ型: 商品ID object 価格 object 数量 object dtype: object
⚠️ 問題点
全ての列がobject(文字列)になっています!
価格と数量は見た目は数字ですが、文字列として扱われています。
このままでは「価格 × 数量」の計算ができません。文字列の掛け算はエラーになるか、意図しない結果になります。
文字列を数値に変換して、計算できるようにしましょう。
コード:数値型に変換して計算
import pandas as pd
data = {
'商品ID': ['001', '002', '003'],
'価格': ['100', '200', '150'],
'数量': ['10', '5', '8']
}
df = pd.DataFrame(data)
# 文字列を整数に変換
# astype(int)で整数型に変換
df['価格'] = df['価格'].astype(int)
df['数量'] = df['数量'].astype(int)
print("変換後のデータ型:")
print(df.dtypes)
print()
# これで計算ができる!
df['合計金額'] = df['価格'] * df['数量']
print("計算結果:")
print(df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
変換後のデータ型: 商品ID object 価格 int64 数量 int64 dtype: object 計算結果: 商品ID 価格 数量 合計金額 0 001 100 10 1000 1 002 200 5 1000 2 003 150 8 1200
💡 コードの解説
df[‘価格’] = df[‘価格’].astype(int)
・df[‘価格’]:価格列を取得
・.astype(int):整数型(int)に変換
・df[‘価格’] =:変換結果を同じ列に上書き保存
df[‘合計金額’] = df[‘価格’] * df[‘数量’]
・数値型になったので掛け算ができる!
・100 × 10 = 1000 のように計算されます
📝 整数と小数の変換
整数(int)と小数(float)を相互に変換することもできます。
コード:整数を小数に変換
import pandas as pd
# 整数データ
numbers = pd.Series([10, 20, 30, 40, 50])
print("元のデータ(整数):")
print(numbers)
print(f"データ型: {numbers.dtype}")
print()
# 小数に変換
numbers_float = numbers.astype(float)
print("小数に変換:")
print(numbers_float)
print(f"データ型: {numbers_float.dtype}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ(整数): 0 10 1 20 2 30 3 40 4 50 dtype: int64 データ型: int64 小数に変換: 0 10.0 1 20.0 2 30.0 3 40.0 4 50.0 dtype: float64 データ型: float64
💡 いつ小数型を使うか?
・割り算の結果を正確に保持したい時
・欠損値(NaN)を含むデータを扱う時(NaNはfloat型でしか扱えません)
・小数点以下の精度が必要な時(金額の計算など)
📝 数値を文字列に変換
数値を文字列に変換すると、文字列操作(ゼロ埋めなど)ができるようになります。
コード:数値を文字列に変換してゼロ埋め
import pandas as pd
data = {
'商品コード': [1, 2, 3],
'価格': [1000, 2000, 1500]
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print(f"商品コードの型: {df['商品コード'].dtype}")
print()
# 商品コードを文字列に変換
df['商品コード'] = df['商品コード'].astype(str)
print("文字列に変換:")
print(df)
print(f"商品コードの型: {df['商品コード'].dtype}")
print()
# ゼロ埋めで5桁にする
# .str.zfill(5)は「文字列の前にゼロを追加して5桁にする」という意味
df['商品コード'] = df['商品コード'].str.zfill(5)
print("5桁にゼロ埋め:")
print(df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 商品コード 価格 0 1 1000 1 2 2000 2 3 1500 商品コードの型: int64 文字列に変換: 商品コード 価格 0 1 1000 1 2 2000 2 3 1500 商品コードの型: object 5桁にゼロ埋め: 商品コード 価格 0 00001 1000 1 00002 2000 2 00003 1500
💡 zfill()の説明
.str.zfill(5)
・str:「この列を文字列として操作する」という意味
・zfill(5):「zero fill」の略で、5桁になるまでゼロを前に追加
・”1″ → “00001”(5桁になるまでゼロを追加)
・商品コードやIDの形式を揃える時に便利です
⚠️ 3. エラーへの対処
数値に変換できない文字(「不明」「なし」など)が含まれていると、astype()はエラーになります。そんな時はpd.to_numeric()を使います。
🔰 変換できない値がある場合の問題
実際のデータには、数値に変換できない値が含まれていることがよくあります。
📝 pd.to_numeric()の書き方
pd.to_numeric(df[‘列名’], errors=’coerce’)
・errors=’raise’:エラーで停止(デフォルト)
・errors=’coerce’:変換できない値をNaN(欠損値)にする
・errors=’ignore’:変換できない値はそのまま残す
・coerce(コアース)は「強制する」という意味。変換できない値を強制的にNaNにします。
コード:変換できない値をNaNにする
import pandas as pd
# 数値に変換できないデータを含む
data = {
'商品': ['A', 'B', 'C', 'D'],
'価格': ['100', '200', '不明', '150']
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print()
# astype(int)だとエラーになる!
# df['価格'].astype(int) # ValueError: invalid literal
# to_numeric()でエラーを回避
# errors='coerce'で変換できない値をNaNにする
df['価格'] = pd.to_numeric(df['価格'], errors='coerce')
print("errors='coerce'で変換:")
print(df)
print(f"\nデータ型: {df['価格'].dtype}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 商品 価格 0 A 100 1 B 200 2 C 不明 3 D 150 errors='coerce'で変換: 商品 価格 0 A 100.0 1 B 200.0 2 C NaN 3 D 150.0 データ型: float64
💡 コードの解説
pd.to_numeric(df[‘価格’], errors=’coerce’)
・「100」「200」「150」は数値に変換される
・「不明」は数値に変換できないのでNaN(欠損値)になる
なぜfloat64になる?
・NaN(欠損値)はfloat型でしか扱えません
・そのため、NaNを含むと自動的にfloat64になります
📝 小数を整数に変換する時の注意
astype(int)で小数を整数に変換すると、小数点以下が切り捨てられます。四捨五入したい場合は、先にround()を使います。
コード:切り捨てと四捨五入の違い
import pandas as pd
# 小数データ
values = pd.Series([10.4, 20.6, 30.5, 40.9])
print("元のデータ:")
print(values)
print()
# そのまま整数に変換(切り捨て)
values_truncated = values.astype(int)
print("切り捨て(astype(int)のみ):")
print(values_truncated)
print()
# 四捨五入してから整数に変換
# round()で四捨五入 → astype(int)で整数に
values_rounded = values.round().astype(int)
print("四捨五入してから整数:")
print(values_rounded)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 0 10.4 1 20.6 2 30.5 3 40.9 dtype: float64 切り捨て(astype(int)のみ): 0 10 1 20 2 30 3 40 dtype: int64 四捨五入してから整数: 0 10 1 21 2 30 3 41 dtype: int64
⚠️ 切り捨てと四捨五入の違いに注意
astype(int):小数点以下を切り捨て
・20.6 → 20(0.6が消える)
・40.9 → 40(0.9が消える)
round().astype(int):四捨五入してから整数に
・20.6 → 21(四捨五入で21、整数で21)
・40.9 → 41(四捨五入で41、整数で41)
目的に応じて使い分けましょう!
📅 4. 日付型への変換
日付データは最初は文字列として読み込まれることが多いです。pd.to_datetime()を使うと、日付型に変換でき、年・月・日の取り出しや日付計算ができるようになります。
🔰 文字列を日付に変換
📝 pd.to_datetime()の書き方
pd.to_datetime(df[‘列名’])
・様々な形式の日付文字列を自動認識します
・「2024-01-15」「2024/01/15」「Jan 15, 2024」など
・変換できない形式の場合は、formatパラメータで明示的に指定できます
コード:文字列を日付型に変換
import pandas as pd
# 日付の文字列データ
data = {
'日付': ['2024-01-01', '2024-01-02', '2024-01-03'],
'売上': [120000, 135000, 142000]
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print(f"日付の型: {df['日付'].dtype}")
print()
# 日付型に変換
df['日付'] = pd.to_datetime(df['日付'])
print("日付型に変換:")
print(df)
print(f"日付の型: {df['日付'].dtype}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ:
日付 売上
0 2024-01-01 120000
1 2024-01-02 135000
2 2024-01-03 142000
日付の型: object
日付型に変換:
日付 売上
0 2024-01-01 120000
1 2024-01-02 135000
2 2024-01-03 142000
日付の型: datetime64[ns]
💡 日付型に変換するメリット
・年・月・日・曜日などを簡単に取り出せる
・日付の差を計算できる(何日経過したかなど)
・日付順に並び替えができる
・月ごと、年ごとの集計が簡単にできる
📝 日付から年・月・日を取り出す
日付型に変換すると、.dtアクセサを使って年・月・日などを取り出せます。
コード:日付の要素を取り出す
import pandas as pd
data = {
'日付': ['2024-01-15', '2024-02-20', '2024-03-10'],
'売上': [120000, 135000, 142000]
}
df = pd.DataFrame(data)
# 日付型に変換
df['日付'] = pd.to_datetime(df['日付'])
# 年・月・日を取り出して新しい列に
# .dtは「datetime(日付時刻)として操作する」という意味
df['年'] = df['日付'].dt.year # 年を取得
df['月'] = df['日付'].dt.month # 月を取得
df['日'] = df['日付'].dt.day # 日を取得
df['曜日'] = df['日付'].dt.day_name() # 曜日名を取得
print("日付の要素を取り出す:")
print(df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
日付の要素を取り出す:
日付 売上 年 月 日 曜日
0 2024-01-15 120000 2024 1 15 Monday
1 2024-02-20 135000 2024 2 20 Tuesday
2 2024-03-10 142000 2024 3 10 Sunday
📌 日付型で使える主なプロパティ
| プロパティ | 説明 | 例 |
| .dt.year | 年を取得 | 2024 |
| .dt.month | 月を取得 | 1, 2, …, 12 |
| .dt.day | 日を取得 | 1, 2, …, 31 |
| .dt.day_name() | 曜日名を取得 | Monday, Tuesday, … |
| .dt.weekday | 曜日番号(0=月曜) | 0, 1, …, 6 |
📝 様々な日付フォーマットに対応
日付は様々な形式で書かれることがあります。pd.to_datetime()は多くの形式を自動認識しますが、特殊な形式の場合はformatパラメータで指定します。
コード:様々な日付フォーマット
import pandas as pd
# 様々な形式の日付
dates = pd.Series([
'2024/01/15', # スラッシュ区切り
'2024-02-20', # ハイフン区切り
'15-Mar-2024' # 日-月名-年
])
print("元のデータ:")
print(dates)
print()
# 自動判定で変換
dates_converted = pd.to_datetime(dates)
print("日付型に変換:")
print(dates_converted)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 0 2024/01/15 1 2024-02-20 2 15-Mar-2024 dtype: object 日付型に変換: 0 2024-01-15 1 2024-02-20 2 2024-03-15 dtype: datetime64[ns]
💡 formatパラメータの使い方
自動認識できない場合は、formatで形式を指定します:
・%Y:4桁の年(2024)
・%m:2桁の月(01〜12)
・%d:2桁の日(01〜31)
例:アメリカ式(月/日/年)の場合
pd.to_datetime('01/15/2024', format='%m/%d/%Y')
🔧 5. 複数列の一括変換
複数の列を一度に変換したい場合は、astype()に辞書を渡します。
📝 複数列一括変換の書き方
df.astype({‘列名1’: 型1, ‘列名2’: 型2, …})
・辞書形式で「列名: 型」のペアを指定します
コード:複数列を一括変換
import pandas as pd
# 全て文字列として格納されたデータ
data = {
'商品': ['A', 'B', 'C'],
'価格': ['1000', '2000', '1500'],
'在庫': ['50', '30', '45'],
'評価': ['4.5', '4.8', '4.2']
}
df = pd.DataFrame(data)
print("元のデータ型:")
print(df.dtypes)
print()
# 複数列を一括変換(辞書で指定)
df = df.astype({
'価格': int, # 整数に
'在庫': int, # 整数に
'評価': float # 小数に
})
print("変換後のデータ型:")
print(df.dtypes)
print()
print("変換後のデータ:")
print(df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ型: 商品 object 価格 object 在庫 object 評価 object dtype: object 変換後のデータ型: 商品 object 価格 int64 在庫 int64 評価 float64 dtype: object 変換後のデータ: 商品 価格 在庫 評価 0 A 1000 50 4.5 1 B 2000 30 4.8 2 C 1500 45 4.2
💡 一括変換のメリット
・コードが短くなる
・どの列をどの型に変換するかが一目でわかる
・変換漏れを防げる
・列ごとに1行ずつ書くより効率的
📝 カテゴリ型への変換(メモリ節約)
同じ値が繰り返し出てくるデータ(地域、性別、カテゴリなど)は、category型に変換するとメモリ使用量を減らせます。
コード:カテゴリ型への変換
import pandas as pd
# 繰り返しの多いデータ
data = {
'地域': ['東京', '大阪', '東京', '名古屋', '大阪',
'東京', '名古屋', '東京', '大阪', '東京']
}
df = pd.DataFrame(data)
print("元のデータ型:")
print(df['地域'].dtype)
print(f"メモリ使用量: {df['地域'].memory_usage(deep=True)} bytes")
print()
# カテゴリ型に変換
df['地域'] = df['地域'].astype('category')
print("カテゴリ型に変換:")
print(df['地域'].dtype)
print(f"メモリ使用量: {df['地域'].memory_usage(deep=True)} bytes")
print()
print("カテゴリの一覧:")
print(df['地域'].cat.categories)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ型: object メモリ使用量: 730 bytes カテゴリ型に変換: category メモリ使用量: 322 bytes カテゴリの一覧: Index(['大阪', '名古屋', '東京'], dtype='object')
💡 カテゴリ型のメリット
・メモリ使用量が減る(上の例では730→322 bytes)
・処理速度が向上する
・カテゴリの一覧を簡単に取得できる
いつ使うべき?
・地域、性別、部署など、同じ値が何度も出てくる列
・大量のデータを扱う時
・ユニークな値が少ない列(名前、IDなどには不向き)
📝 練習問題
ここまで学んだことを、実際に手を動かして確認しましょう。
問題1:文字列を数値に変換(初級)
📋 問題
以下のデータの「価格」と「数量」を数値型に変換し、「合計」列を計算してください。
・商品: [‘りんご’, ‘バナナ’, ‘みかん’]
・価格: [‘120’, ‘180’, ‘100’]
・数量: [‘5’, ‘3’, ‘8’]
解答例を見る
コード
import pandas as pd
data = {
'商品': ['りんご', 'バナナ', 'みかん'],
'価格': ['120', '180', '100'],
'数量': ['5', '3', '8']
}
df = pd.DataFrame(data)
# 数値型に変換
df['価格'] = df['価格'].astype(int)
df['数量'] = df['数量'].astype(int)
# 合計を計算
df['合計'] = df['価格'] * df['数量']
print("結果:")
print(df)
print("\nデータ型:")
print(df.dtypes)
実行結果
結果: 商品 価格 数量 合計 0 りんご 120 5 600 1 バナナ 180 3 540 2 みかん 100 8 800 データ型: 商品 object 価格 int64 数量 int64 合計 int64 dtype: object
問題2:四捨五入して整数に(初級)
📋 問題
以下の評価データを四捨五入して整数に変換してください。
ratings = pd.Series([4.2, 4.8, 3.5, 4.9, 3.1, 4.6])
解答例を見る
コード
import pandas as pd
ratings = pd.Series([4.2, 4.8, 3.5, 4.9, 3.1, 4.6])
print("元のデータ:")
print(ratings)
# 四捨五入して整数に変換
ratings_int = ratings.round().astype(int)
print("\n四捨五入して整数に:")
print(ratings_int)
実行結果
元のデータ: 0 4.2 1 4.8 2 3.5 3 4.9 4 3.1 5 4.6 dtype: float64 四捨五入して整数に: 0 4 1 5 2 4 3 5 4 3 5 5 dtype: int64
問題3:エラー処理付きの変換(中級)
📋 問題
以下のデータには変換できない値が含まれています。to_numeric()を使って、変換できない値をNaNにしてください。
・商品: [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]
・売上: [‘1000’, ‘2000’, ‘不明’, ‘1500’, ‘なし’]
解答例を見る
コード
import pandas as pd
data = {
'商品': ['A', 'B', 'C', 'D', 'E'],
'売上': ['1000', '2000', '不明', '1500', 'なし']
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
# エラーを無視して変換(NaNに)
df['売上'] = pd.to_numeric(df['売上'], errors='coerce')
print("\n変換後:")
print(df)
print(f"\nデータ型: {df['売上'].dtype}")
# 有効なデータの統計
print(f"\n有効なデータ数: {df['売上'].notna().sum()}個")
print(f"平均売上: {df['売上'].mean():.0f}円")
実行結果
元のデータ: 商品 売上 0 A 1000 1 B 2000 2 C 不明 3 D 1500 4 E なし 変換後: 商品 売上 0 A 1000.0 1 B 2000.0 2 C NaN 3 D 1500.0 4 E NaN データ型: float64 有効なデータ数: 3個 平均売上: 1500円
問題4:日付型への変換と月の取り出し(中級)
📋 問題
以下の売上データの「日付」を日付型に変換し、月を取り出して新しい列に追加してください。
・日付: [‘2024-01-15’, ‘2024-01-20’, ‘2024-02-10’, ‘2024-02-25’, ‘2024-03-05’]
・売上: [12000, 15000, 13000, 14000, 16000]
解答例を見る
コード
import pandas as pd
data = {
'日付': ['2024-01-15', '2024-01-20', '2024-02-10',
'2024-02-25', '2024-03-05'],
'売上': [12000, 15000, 13000, 14000, 16000]
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
# 日付型に変換
df['日付'] = pd.to_datetime(df['日付'])
# 月を取り出す
df['月'] = df['日付'].dt.month
print("\n日付型に変換後:")
print(df)
print(f"\n日付のデータ型: {df['日付'].dtype}")
実行結果
元のデータ:
日付 売上
0 2024-01-15 12000
1 2024-01-20 15000
2 2024-02-10 13000
3 2024-02-25 14000
4 2024-03-05 16000
日付型に変換後:
日付 売上 月
0 2024-01-15 12000 1
1 2024-01-20 15000 1
2 2024-02-10 13000 2
3 2024-02-25 14000 2
4 2024-03-05 16000 3
日付のデータ型: datetime64[ns]
問題5:複数列の型変換と検証(上級)
📋 問題
以下のデータについて、各列を適切な型に変換し、変換できなかった値を確認してください。
・ID: [‘1’, ‘2’, ‘3’, ‘4’, ‘5’]
・名前: [‘太郎’, ‘花子’, ‘次郎’, ‘美咲’, ‘健太’]
・年齢: [’25’, ’30’, ‘unknown’, ’28’, ’35’]
・給料: [‘300000’, ‘350000’, ‘400000’, ‘N/A’, ‘450000’]
解答例を見る
コード
import pandas as pd
data = {
'ID': ['1', '2', '3', '4', '5'],
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'年齢': ['25', '30', 'unknown', '28', '35'],
'給料': ['300000', '350000', '400000', 'N/A', '450000']
}
df = pd.DataFrame(data)
print("【変換前のデータ型】")
print(df.dtypes)
# データ型を変換
df['ID'] = df['ID'].astype(int)
df['年齢'] = pd.to_numeric(df['年齢'], errors='coerce')
df['給料'] = pd.to_numeric(df['給料'], errors='coerce')
print("\n【変換後のデータ型】")
print(df.dtypes)
print("\n【変換後のデータ】")
print(df)
# 変換できなかった値を確認
print("\n【変換できなかった値の確認】")
print(f"年齢の欠損: {df['年齢'].isnull().sum()}件")
print(f"給料の欠損: {df['給料'].isnull().sum()}件")
実行結果
【変換前のデータ型】 ID object 名前 object 年齢 object 給料 object dtype: object 【変換後のデータ型】 ID int64 名前 object 年齢 float64 給料 float64 dtype: object 【変換後のデータ】 ID 名前 年齢 給料 0 1 太郎 25.0 300000.0 1 2 花子 30.0 350000.0 2 3 次郎 NaN 400000.0 3 4 美咲 28.0 NaN 4 5 健太 35.0 450000.0 【変換できなかった値の確認】 年齢の欠損: 1件 給料の欠損: 1件
問題6:総合演習(上級)
📋 問題
以下の売上データについて:
1. 日付を日付型に変換
2. 金額を数値型に変換(変換できない値はNaNに)
3. 月を取り出して新しい列に追加
4. 有効なデータの月別合計を計算
・日付: [‘2024-01-10’, ‘2024-01-25’, ‘2024-02-15’, ‘2024-02-28’]
・金額: [‘50000’, ‘60000’, ‘エラー’, ‘70000’]
解答例を見る
コード
import pandas as pd
data = {
'日付': ['2024-01-10', '2024-01-25', '2024-02-15', '2024-02-28'],
'金額': ['50000', '60000', 'エラー', '70000']
}
df = pd.DataFrame(data)
print("【元のデータ】")
print(df)
# 1. 日付を日付型に変換
df['日付'] = pd.to_datetime(df['日付'])
# 2. 金額を数値型に変換
df['金額'] = pd.to_numeric(df['金額'], errors='coerce')
# 3. 月を取り出す
df['月'] = df['日付'].dt.month
print("\n【変換後のデータ】")
print(df)
# 4. 月別合計(NaNは自動的に無視される)
print("\n【月別の売上合計】")
monthly_sum = df.groupby('月')['金額'].sum()
print(monthly_sum)
print(f"\n有効なデータ数: {df['金額'].notna().sum()}件")
実行結果
【元のデータ】
日付 金額
0 2024-01-10 50000
1 2024-01-25 60000
2 2024-02-15 エラー
3 2024-02-28 70000
【変換後のデータ】
日付 金額 月
0 2024-01-10 50000.0 1
1 2024-01-25 60000.0 1
2 2024-02-15 NaN 2
3 2024-02-28 70000.0 2
【月別の売上合計】
月
1 110000.0
2 70000.0
Name: 金額, dtype: float64
有効なデータ数: 3件
🎯 このステップのまとめ
✅ 学んだこと
✓ データには型(整数、小数、文字列など)がある
✓ dtypesでデータ型を確認できる
✓ astype()でデータ型を変換できる
✓ pd.to_numeric()で変換できない値をNaNにできる
✓ pd.to_datetime()で日付型に変換できる
✓ 日付型から年・月・日を.dtで取り出せる
✓ 辞書を使って複数列を一括変換できる
✓ カテゴリ型でメモリ使用量を節約できる
💡 次のステップに進む前に確認
以下のことができるようになったか確認しましょう:
□ dtypesでデータ型を確認できますか?
□ astype()でデータ型を変換できますか?
□ to_numeric()でエラー処理できますか?
□ 日付型に変換できますか?
□ 日付から年・月・日を取り出せますか?
これらができたら、次のステップに進みましょう!
❓ よくある質問
Q1: astype()とto_numeric()の違いは?
A: astype()は変換できない値があるとエラーになります。to_numeric()はerrors=’coerce’オプションで変換できない値をNaNにできるので、実データを扱う時に便利です。データがきれいな場合はastype()、不明な値が含まれる可能性がある場合はto_numeric()を使いましょう。
Q2: int64とfloat64、どちらを使うべき?
A: 小数が不要ならint64、小数が必要ならfloat64を使います。ただし、欠損値(NaN)を含む数値データは自動的にfloat64になります。これはNaNがfloat型でしか表現できないためです。
Q3: 日付の文字列が自動認識されません
A: 日付のフォーマットが特殊な場合、pd.to_datetime(df['日付'], format='%Y/%m/%d')のようにformatパラメータで明示的に指定してください。%Yは4桁の年、%mは2桁の月、%dは2桁の日を表します。
Q4: 変換は元のデータを変更しますか?
A: df['列名'] = df['列名'].astype(型)と代入すれば元のデータが変わります。元を残したい場合はdf_new = df.copy()でコピーしてから変換しましょう。
Q5: CSVを読み込む時に型を指定できますか?
A: はい、pd.read_csv('file.csv', dtype={'列名': int})のようにdtypeパラメータで指定できます。大きなデータを読み込む時は、最初から型を指定すると効率的です。
学習メモ
Pythonデータ分析入門 - Step 28