📋 このステップで学ぶこと
- カラムの追加・削除・変更・並び替え
- 条件に基づくデータ変更(loc、np.where、np.select)
- 文字列操作(split、strip、replace、contains、extract)
- 日付データの処理(変換、抽出、計算、フィルタ)
- カテゴリデータの変換(ラベルエンコーディング、ワンホットエンコーディング)
⏱️ 学習時間の目安:2.5時間
📝 練習問題:15問(基礎6問・応用6問・発展3問)
🎯 1. カラムの追加・削除・変更
1-1. データ変換とは?
ETLの「T(Transform)」の中心的な作業がデータ変換です。
生のデータを分析・機械学習に使える形に整えます。
🍳 例え話:料理の下ごしらえ
野菜をそのまま鍋に入れることはありません。
皮を剥く(不要なカラムを削除)、切る(文字列を分割)、下味をつける(データ型を変換)…
データ変換は、分析という「料理」のための下ごしらえです!
1-2. 新しいカラムを追加する
# ===== カラムの追加方法 =====
import pandas as pd
df = pd.DataFrame({
‘product’: [‘ノートPC’, ‘マウス’, ‘キーボード’],
‘price’: [89800, 1980, 4500],
‘quantity’: [2, 5, 3]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: 直接代入(最も一般的)
df[‘total’] = df[‘price’] * df[‘quantity’]
# 方法2: 税込価格を追加
df[‘total_with_tax’] = df[‘total’] * 1.1
# 方法3: assign()を使う(元のDataFrameは変更されない)
df2 = df.assign(
discount=lambda x: x[‘total’] * 0.1,
final_price=lambda x: x[‘total’] – x[‘total’] * 0.1
)
print(“\n=== カラム追加後 ===”)
print(df)
print(“\n=== assign()で追加 ===”)
print(df2)
【実行結果】
=== 元のデータ ===
product price quantity
0 ノートPC 89800 2
1 マウス 1980 5
2 キーボード 4500 3
=== カラム追加後 ===
product price quantity total total_with_tax
0 ノートPC 89800 2 179600 197560.0
1 マウス 1980 5 9900 10890.0
2 キーボード 4500 3 13500 14850.0
1-3. カラムを削除する
# ===== カラムの削除方法 =====
import pandas as pd
df = pd.DataFrame({
‘A’: [1, 2, 3],
‘B’: [4, 5, 6],
‘C’: [7, 8, 9],
‘D’: [10, 11, 12]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: drop()で削除(元のDataFrameは変更されない)
df1 = df.drop(‘C’, axis=1)
print(“\n=== drop(‘C’)後 ===”)
print(df1)
# 方法2: 複数カラムを削除
df2 = df.drop([‘B’, ‘C’], axis=1)
print(“\n=== drop([‘B’, ‘C’])後 ===”)
print(df2)
# 方法3: inplace=Trueで元のDataFrameを変更
df_copy = df.copy()
df_copy.drop(‘D’, axis=1, inplace=True)
print(“\n=== inplace=True後 ===”)
print(df_copy)
# 方法4: del文で削除(元のDataFrameを変更)
df_copy2 = df.copy()
del df_copy2[‘A’]
print(“\n=== del後 ===”)
print(df_copy2)
⚠️ drop()の注意点
drop()だけでは元のDataFrameは変更されない
- 変更を反映するには
df = df.drop(...)かinplace=Trueを使う
axis=1は「列方向」、axis=0は「行方向」
1-4. カラム名を変更する
# ===== カラム名の変更方法 =====
import pandas as pd
df = pd.DataFrame({
‘old_name1’: [1, 2, 3],
‘old_name2’: [4, 5, 6]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: rename()で特定のカラムを変更
df1 = df.rename(columns={
‘old_name1’: ‘new_name1’,
‘old_name2’: ‘new_name2’
})
print(“\n=== rename()後 ===”)
print(df1)
# 方法2: すべてのカラム名を一度に変更
df2 = df.copy()
df2.columns = [‘A’, ‘B’]
print(“\n=== columns属性で変更後 ===”)
print(df2)
# 方法3: 日本語カラム名を英語に一括変換
df_jp = pd.DataFrame({
‘商品名’: [‘ノートPC’, ‘マウス’],
‘価格’: [89800, 1980],
‘数量’: [2, 5]
})
column_mapping = {
‘商品名’: ‘product’,
‘価格’: ‘price’,
‘数量’: ‘quantity’
}
df_en = df_jp.rename(columns=column_mapping)
print(“\n=== 日本語→英語 ===”)
print(df_en)
1-5. カラムの順序を変更する
# ===== カラムの並び替え =====
import pandas as pd
df = pd.DataFrame({
‘C’: [7, 8, 9],
‘A’: [1, 2, 3],
‘B’: [4, 5, 6]
})
print(“=== 元のデータ(C, A, B の順)===”)
print(df)
# 方法1: 希望の順序でカラムを指定
df1 = df[[‘A’, ‘B’, ‘C’]]
print(“\n=== A, B, C の順に並び替え ===”)
print(df1)
# 方法2: 特定のカラムを先頭に移動
cols = [‘B’] + [col for col in df.columns if col != ‘B’]
df2 = df[cols]
print(“\n=== B を先頭に移動 ===”)
print(df2)
# 方法3: アルファベット順にソート
df3 = df[sorted(df.columns)]
print(“\n=== アルファベット順 ===”)
print(df3)
1-6. 条件に基づいてカラムの値を変更する
データ分析では、条件に基づいて値を変更することが頻繁にあります。
# ===== 条件付きでデータを変更 =====
import pandas as pd
import numpy as np
df = pd.DataFrame({
‘name’: [‘田中’, ‘佐藤’, ‘鈴木’, ‘山田’, ‘高橋’],
‘age’: [15, 25, 35, 45, 65],
‘price’: [1000, 1500, 2000, 2500, 3000]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: loc[]を使う(条件に一致する行を変更)
df[‘category’] = ” # 空のカラムを作成
df.loc[df[‘age’] < 20, 'category'] = '未成年'
df.loc[(df['age'] >= 20) & (df[‘age’] < 60), 'category'] = '成人'
df.loc[df['age'] >= 60, ‘category’] = ‘シニア’
print(“\n=== loc[]で分類後 ===”)
print(df)
# 方法2: np.where()を使う(三項演算子のように使える)
df[‘discount’] = np.where(df[‘price’] >= 2000, 0.1, 0)
print(“\n=== np.where()で割引率設定後 ===”)
print(df)
【実行結果】
=== loc[]で分類後 ===
name age price category
0 田中 15 1000 未成年
1 佐藤 25 1500 成人
2 鈴木 35 2000 成人
3 山田 45 2500 成人
4 高橋 65 3000 シニア
=== np.where()で割引率設定後 ===
name age price category discount
0 田中 15 1000 未成年 0.0
1 佐藤 25 1500 成人 0.0
2 鈴木 35 2000 成人 0.1
3 山田 45 2500 成人 0.1
4 高橋 65 3000 シニア 0.1
1-7. np.select()で複数条件を処理
# ===== np.select()で複数条件を一度に処理 =====
import pandas as pd
import numpy as np
df = pd.DataFrame({
‘score’: [95, 82, 68, 45, 30]
})
print(“=== 元のデータ ===”)
print(df)
# 複数条件をリストで定義
conditions = [
df[‘score’] >= 90, # 条件1: 90点以上
(df[‘score’] >= 70) & (df[‘score’] < 90), # 条件2: 70-89点
(df['score'] >= 50) & (df[‘score’] < 70), # 条件3: 50-69点
df['score'] < 50 # 条件4: 50点未満
]
# 各条件に対応する値
choices = ['A', 'B', 'C', 'D']
# np.select()で一度に処理
df['grade'] = np.select(conditions, choices, default='不明')
print("\n=== 成績ランク追加後 ===")
print(df)
【実行結果】
=== 成績ランク追加後 ===
score grade
0 95 A
1 82 B
2 68 C
3 45 D
4 30 D
条件分岐メソッドの比較
| メソッド |
条件数 |
使いどころ |
loc[] |
1つずつ |
シンプルな条件分岐、直感的でわかりやすい |
np.where() |
2択 |
True/Falseで値を分ける場合 |
np.select() |
複数 |
3つ以上の条件分岐を一度に処理 |
✂️ 2. 文字列操作
2-1. 文字列メソッドの基本(.str)
Pandasでは、.strを使ってSeries全体に文字列操作を適用できます。
# ===== 基本的な文字列操作 =====
import pandas as pd
df = pd.DataFrame({
‘name’: [‘ 山田太郎 ‘, ‘SATO HANAKO’, ‘鈴木 一郎’, ‘tanaka-mika’]
})
print(“=== 元のデータ ===”)
print(df)
# 1. 前後の空白を削除
df[‘strip’] = df[‘name’].str.strip()
# 2. 小文字に変換
df[‘lower’] = df[‘name’].str.lower()
# 3. 大文字に変換
df[‘upper’] = df[‘name’].str.upper()
# 4. 文字数を取得
df[‘length’] = df[‘name’].str.len()
# 5. 特定の文字を含むか判定
df[‘has_space’] = df[‘name’].str.contains(‘ ‘)
print(“\n=== 文字列操作後 ===”)
print(df)
主な文字列メソッド一覧
| メソッド |
説明 |
例 |
.str.strip() |
前後の空白を削除 |
‘ hello ‘ → ‘hello’ |
.str.lower() |
小文字に変換 |
‘HELLO’ → ‘hello’ |
.str.upper() |
大文字に変換 |
‘hello’ → ‘HELLO’ |
.str.len() |
文字数を取得 |
‘hello’ → 5 |
.str.replace() |
文字を置換 |
‘a-b-c’ → ‘a_b_c’ |
.str.split() |
文字で分割 |
‘a,b,c’ → [‘a’,’b’,’c’] |
2-2. 文字列の分割(split)
# ===== splitで文字列を分割 =====
import pandas as pd
df = pd.DataFrame({
‘full_name’: [‘山田 太郎’, ‘佐藤 花子’, ‘鈴木 一郎’]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: splitしてリストに
df[‘name_list’] = df[‘full_name’].str.split(‘ ‘)
print(“\n=== リストとして取得 ===”)
print(df)
# 方法2: splitして新しいカラムに展開(expand=True)
df[[‘last_name’, ‘first_name’]] = df[‘full_name’].str.split(‘ ‘, expand=True)
print(“\n=== 新しいカラムに展開 ===”)
print(df)
# メールアドレスを@で分割
df2 = pd.DataFrame({
‘email’: [‘yamada@example.com’, ‘sato@test.jp’, ‘suzuki@company.co.jp’]
})
df2[[‘user’, ‘domain’]] = df2[‘email’].str.split(‘@’, expand=True)
print(“\n=== メールアドレスの分割 ===”)
print(df2)
【実行結果】
=== 新しいカラムに展開 ===
full_name name_list last_name first_name
0 山田 太郎 [山田, 太郎] 山田 太郎
1 佐藤 花子 [佐藤, 花子] 佐藤 花子
2 鈴木 一郎 [鈴木, 一郎] 鈴木 一郎
=== メールアドレスの分割 ===
email user domain
0 yamada@example.com yamada example.com
1 sato@test.jp sato test.jp
2 suzuki@company.co.jp suzuki company.co.jp
2-3. 文字列の置換(replace)
# ===== replaceで文字列を置換 =====
import pandas as pd
df = pd.DataFrame({
‘phone’: [’03-1234-5678′, ‘090-9876-5432′, ’06-5555-6666’]
})
print(“=== 元のデータ ===”)
print(df)
# ハイフンを削除
df[‘phone_clean’] = df[‘phone’].str.replace(‘-‘, ”)
# 正規表現で複数の文字を削除(regex=True)
df[‘phone_numbers’] = df[‘phone’].str.replace(r'[-()]’, ”, regex=True)
print(“\n=== ハイフン削除後 ===”)
print(df)
# 複数の置換をチェーンで実行
df2 = pd.DataFrame({
‘text’: [‘Hello World’, ‘Good Morning’, ‘Nice Day’]
})
df2[‘text_ja’] = df2[‘text’].str.replace(‘Hello’, ‘こんにちは’)\
.str.replace(‘World’, ‘世界’)\
.str.replace(‘Good’, ‘良い’)\
.str.replace(‘Morning’, ‘朝’)
print(“\n=== 複数置換 ===”)
print(df2)
2-4. 文字列の検索と抽出(contains、extract)
# ===== 文字列の検索と抽出 =====
import pandas as pd
df = pd.DataFrame({
‘product’: [‘ノートPC Core i5’, ‘マウス Bluetooth’, ‘キーボード 無線’, ‘モニター 24インチ’]
})
print(“=== 元のデータ ===”)
print(df)
# 1. 特定の文字列を含むか判定(contains)
df[‘has_wireless’] = df[‘product’].str.contains(‘無線|Bluetooth’)
# 2. 数値を含むか判定(正規表現)
df[‘has_number’] = df[‘product’].str.contains(r’\d+’)
# 3. 数値を抽出(extract)
df[‘number’] = df[‘product’].str.extract(r'(\d+)’, expand=False)
# 4. 先頭の単語を抽出
df[‘category’] = df[‘product’].str.extract(r’^(\S+)’, expand=False)
print(“\n=== 検索・抽出後 ===”)
print(df)
【実行結果】
=== 検索・抽出後 ===
product has_wireless has_number number category
0 ノートPC Core i5 False True 5 ノートPC
1 マウス Bluetooth True False None マウス
2 キーボード 無線 True False None キーボード
3 モニター 24インチ False True 24 モニター
2-5. 実践例:住所データの分割
# ===== 住所データの処理 =====
import pandas as pd
df = pd.DataFrame({
‘address’: [
‘東京都渋谷区渋谷1-2-3’,
‘大阪府大阪市北区梅田4-5-6’,
‘福岡県福岡市博多区博多駅前7-8-9’
]
})
print(“=== 元のデータ ===”)
print(df)
# 都道府県を抽出(2〜3文字 + 都道府県)
df[‘prefecture’] = df[‘address’].str.extract(r'(.{2,3}[都道府県])’, expand=False)
# 市区町村を抽出
df[‘city’] = df[‘address’].str.extract(r'[都道府県](.+?[市区町村])’, expand=False)
# 番地を抽出
df[‘block’] = df[‘address’].str.extract(r'(\d+-\d+-\d+)’, expand=False)
print(“\n=== 住所分割後 ===”)
print(df)
# 郵便番号の抽出例
df2 = pd.DataFrame({
‘text’: [‘郵便番号は123-4567です’, ‘〒100-0001に送付してください’]
})
df2[‘zipcode’] = df2[‘text’].str.extract(r'(\d{3}-\d{4})’, expand=False)
print(“\n=== 郵便番号抽出 ===”)
print(df2)
📅 3. 日付データの処理
3-1. 日付型への変換
文字列で格納された日付は、pd.to_datetime()で日付型に変換します。
# ===== 日付型への変換 =====
import pandas as pd
df = pd.DataFrame({
‘date_str’: [‘2024-01-01’, ‘2024-01-02’, ‘2024-01-03’]
})
print(“=== 元のデータ(文字列型)===”)
print(df)
print(f”データ型: {df[‘date_str’].dtype}”)
# 文字列 → 日付型に変換
df[‘date’] = pd.to_datetime(df[‘date_str’])
print(“\n=== 変換後(日付型)===”)
print(df)
print(f”データ型: {df[‘date’].dtype}”)
3-2. 様々な日付形式の変換
# ===== 様々な日付形式の変換 =====
import pandas as pd
df = pd.DataFrame({
‘format1’: [‘2024/01/01’, ‘2024/01/02’],
‘format2′: [’01-Jan-2024′, ’02-Jan-2024’],
‘format3’: [‘2024年1月1日’, ‘2024年1月2日’],
‘format4’: [‘20240101’, ‘20240102’]
})
print(“=== 元のデータ ===”)
print(df)
# 自動認識(スラッシュ区切り)
df[‘date1’] = pd.to_datetime(df[‘format1’])
# format指定(英語の月名)
df[‘date2’] = pd.to_datetime(df[‘format2′], format=’%d-%b-%Y’)
# format指定(日本語)
df[‘date3’] = pd.to_datetime(df[‘format3′], format=’%Y年%m月%d日’)
# format指定(区切りなし)
df[‘date4’] = pd.to_datetime(df[‘format4′], format=’%Y%m%d’)
print(“\n=== 変換後 ===”)
print(df[[‘date1’, ‘date2’, ‘date3’, ‘date4’]])
日付フォーマットコード一覧
| コード |
意味 |
例 |
%Y |
4桁の年 |
2024 |
%m |
2桁の月(01-12) |
01, 12 |
%d |
2桁の日(01-31) |
01, 31 |
%H |
24時間制の時(00-23) |
09, 23 |
%M |
分(00-59) |
30, 59 |
%S |
秒(00-59) |
00, 59 |
%b |
英語の月名(短縮) |
Jan, Dec |
3-3. 日付から要素を抽出(.dt)
# ===== 日付の要素を取得 =====
import pandas as pd
df = pd.DataFrame({
‘date’: pd.to_datetime([‘2024-01-15’, ‘2024-02-20’, ‘2024-03-25’])
})
print(“=== 元のデータ ===”)
print(df)
# 年・月・日を抽出
df[‘year’] = df[‘date’].dt.year
df[‘month’] = df[‘date’].dt.month
df[‘day’] = df[‘date’].dt.day
# 曜日を取得(0=月曜, 6=日曜)
df[‘dayofweek’] = df[‘date’].dt.dayofweek
# 曜日名を取得(英語)
df[‘day_name’] = df[‘date’].dt.day_name()
# 年月を取得(集計用)
df[‘year_month’] = df[‘date’].dt.to_period(‘M’)
# 四半期を取得
df[‘quarter’] = df[‘date’].dt.quarter
print(“\n=== 要素抽出後 ===”)
print(df)
【実行結果】
=== 要素抽出後 ===
date year month day dayofweek day_name year_month quarter
0 2024-01-15 2024 1 15 0 Monday 2024-01 1
1 2024-02-20 2024 2 20 1 Tuesday 2024-02 1
2 2024-03-25 2024 3 25 0 Monday 2024-03 1
3-4. 日付の計算
# ===== 日付の加算・減算 =====
import pandas as pd
df = pd.DataFrame({
‘order_date’: pd.to_datetime([‘2024-01-01’, ‘2024-01-15’, ‘2024-02-01’])
})
print(“=== 元のデータ ===”)
print(df)
# 日付に日数を加算
df[‘delivery_date’] = df[‘order_date’] + pd.Timedelta(days=3)
# 日付に月を加算
df[‘next_month’] = df[‘order_date’] + pd.DateOffset(months=1)
# 日付の差を計算(日数)
df[‘days_diff’] = (df[‘delivery_date’] – df[‘order_date’]).dt.days
# 今日との差を計算
df[‘days_from_today’] = (pd.Timestamp.now() – df[‘order_date’]).dt.days
print(“\n=== 日付計算後 ===”)
print(df)
3-5. 日付でフィルタリング
# ===== 日付でデータを絞り込む =====
import pandas as pd
df = pd.DataFrame({
‘order_date’: pd.to_datetime([
‘2024-01-01’, ‘2024-01-15’, ‘2024-02-01’,
‘2024-02-15’, ‘2024-03-01’
]),
‘amount’: [10000, 15000, 20000, 18000, 22000]
})
print(“=== 元のデータ ===”)
print(df)
# 1月のデータを抽出
jan_data = df[(df[‘order_date’] >= ‘2024-01-01’) &
(df[‘order_date’] < '2024-02-01')]
print("\n=== 1月のデータ ===")
print(jan_data)
# 特定の期間(1/15〜2/15)
period_data = df[(df['order_date'] >= ‘2024-01-15’) &
(df[‘order_date’] <= '2024-02-15')]
print("\n=== 1/15〜2/15のデータ ===")
print(period_data)
# 月でフィルタ(.dt.monthを使う)
feb_data = df[df['order_date'].dt.month == 2]
print("\n=== 2月のデータ(.dt.month使用)===")
print(feb_data)
3-6. 実践例:売上データの日付処理
# ===== 実践的な日付処理 =====
import pandas as pd
df = pd.DataFrame({
‘order_id’: [1, 2, 3, 4, 5],
‘order_date’: [‘2024-01-15 14:30:00’, ‘2024-01-16 09:15:00’,
‘2024-02-01 18:45:00’, ‘2024-02-15 11:20:00’,
‘2024-03-01 16:10:00’],
‘amount’: [10000, 15000, 20000, 18000, 22000]
})
# 日付型に変換
df[‘order_date’] = pd.to_datetime(df[‘order_date’])
# 年月を追加(集計用)
df[‘year_month’] = df[‘order_date’].dt.to_period(‘M’)
# 曜日を追加(日本語)
weekday_ja = {0: ‘月’, 1: ‘火’, 2: ‘水’, 3: ‘木’, 4: ‘金’, 5: ‘土’, 6: ‘日’}
df[‘weekday’] = df[‘order_date’].dt.dayofweek.map(weekday_ja)
# 時間帯を分類
df[‘time_period’] = pd.cut(
df[‘order_date’].dt.hour,
bins=[0, 6, 12, 18, 24],
labels=[‘深夜’, ‘午前’, ‘午後’, ‘夜間’],
right=False
)
print(“=== 日付処理後 ===”)
print(df)
# 月ごとの売上集計
monthly_sales = df.groupby(‘year_month’)[‘amount’].sum()
print(“\n=== 月別売上 ===”)
print(monthly_sales)
🏷️ 4. カテゴリデータの変換
4-1. カテゴリ型とは?
カテゴリ型は、限られた値を持つデータ(性別、都道府県、ランクなど)を効率的に扱うデータ型です。
✅ カテゴリ型のメリット
- メモリ節約:文字列を数値コードで管理するため、メモリ使用量が減る
- 処理速度向上:内部的に数値で管理するため、比較が高速
- 順序の指定:S < M < L のような順序を定義できる
# ===== カテゴリ型への変換 =====
import pandas as pd
df = pd.DataFrame({
‘gender’: [‘男’, ‘女’, ‘男’, ‘女’, ‘男’] * 1000, # 5000行
‘city’: [‘東京’, ‘大阪’, ‘東京’, ‘福岡’, ‘大阪’] * 1000
})
print(“=== 変換前 ===”)
print(f”データ型: {df.dtypes}”)
print(f”メモリ: {df.memory_usage(deep=True).sum():,} bytes”)
# カテゴリ型に変換
df[‘gender’] = df[‘gender’].astype(‘category’)
df[‘city’] = df[‘city’].astype(‘category’)
print(“\n=== 変換後 ===”)
print(f”データ型: {df.dtypes}”)
print(f”メモリ: {df.memory_usage(deep=True).sum():,} bytes”)
【実行結果】
=== 変換前 ===
メモリ: 580,128 bytes
=== 変換後 ===
メモリ: 20,416 bytes
→ 約96%のメモリ削減!
4-2. ラベルエンコーディング
ラベルエンコーディングは、カテゴリを数値(0, 1, 2…)に変換する方法です。
# ===== ラベルエンコーディング =====
import pandas as pd
df = pd.DataFrame({
‘size’: [‘S’, ‘M’, ‘L’, ‘M’, ‘S’, ‘XL’]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: カテゴリコードを使う
df[‘size_cat’] = df[‘size’].astype(‘category’)
df[‘size_code’] = df[‘size_cat’].cat.codes
print(“\n=== cat.codesでエンコード ===”)
print(df)
# 方法2: mapで手動変換(順序を明示的に指定)
size_mapping = {‘S’: 0, ‘M’: 1, ‘L’: 2, ‘XL’: 3}
df[‘size_mapped’] = df[‘size’].map(size_mapping)
print(“\n=== mapで手動エンコード ===”)
print(df)
# 方法3: sklearn の LabelEncoder
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df[‘size_sklearn’] = le.fit_transform(df[‘size’])
print(“\n=== LabelEncoderでエンコード ===”)
print(df)
print(f”\nラベル一覧: {le.classes_}”)
4-3. ワンホットエンコーディング
ワンホットエンコーディングは、カテゴリをダミー変数(0と1)に変換する方法です。
機械学習で最もよく使われます。
# ===== ワンホットエンコーディング =====
import pandas as pd
df = pd.DataFrame({
‘color’: [‘赤’, ‘青’, ‘緑’, ‘赤’, ‘青’]
})
print(“=== 元のデータ ===”)
print(df)
# 方法1: pd.get_dummies()
dummies = pd.get_dummies(df[‘color’], prefix=’color’)
print(“\n=== ワンホットエンコーディング ===”)
print(dummies)
# DataFrameに結合
df_with_dummies = pd.concat([df, dummies], axis=1)
print(“\n=== 元のDataFrameに結合 ===”)
print(df_with_dummies)
# 方法2: drop_first=True(多重共線性を回避)
dummies_dropped = pd.get_dummies(df[‘color’], prefix=’color’, drop_first=True)
print(“\n=== drop_first=True(1列削除)===”)
print(dummies_dropped)
【実行結果】
=== ワンホットエンコーディング ===
color_緑 color_赤 color_青
0 False True False
1 False False True
2 True False False
3 False True False
4 False False True
=== drop_first=True(1列削除)===
color_赤 color_青
0 True False
1 False True
2 False False
3 True False
4 False True
⚠️ drop_first=True の意味
3つのカテゴリ(赤、青、緑)がある場合、2つの列(赤、青)があれば緑は判断できます。
(赤=0, 青=0 なら緑)
この冗長性を多重共線性といい、機械学習で問題になることがあります。
drop_first=Trueでこれを回避できます。
4-4. 順序付きカテゴリ
# ===== 順序のあるカテゴリデータ =====
import pandas as pd
df = pd.DataFrame({
‘grade’: [‘A’, ‘B’, ‘C’, ‘A’, ‘B’, ‘C’, ‘A’]
})
print(“=== 元のデータ ===”)
print(df)
# 順序を指定してカテゴリ化
df[‘grade_cat’] = pd.Categorical(
df[‘grade’],
categories=[‘C’, ‘B’, ‘A’], # C < B < A の順序
ordered=True
)
# 順序通りに並び替え
df_sorted = df.sort_values('grade_cat')
print("\n=== 順序付きカテゴリでソート ===")
print(df_sorted)
# 比較演算が可能
df['is_good'] = df['grade_cat'] >= ‘B’
print(“\n=== B以上かどうか ===”)
print(df)
4-5. 実践例:アンケートデータの変換
# ===== 実践的なカテゴリ変換 =====
import pandas as pd
df = pd.DataFrame({
‘satisfaction’: [‘非常に満足’, ‘満足’, ‘普通’, ‘不満’, ‘非常に不満’],
‘age_group’: [’20代’, ’30代’, ’20代’, ’40代’, ’30代’]
})
print(“=== 元のデータ ===”)
print(df)
# 満足度を数値に変換(順序を考慮)
satisfaction_mapping = {
‘非常に不満’: 1,
‘不満’: 2,
‘普通’: 3,
‘満足’: 4,
‘非常に満足’: 5
}
df[‘satisfaction_score’] = df[‘satisfaction’].map(satisfaction_mapping)
# 年代をワンホットエンコーディング
age_dummies = pd.get_dummies(df[‘age_group’], prefix=’age’)
df = pd.concat([df, age_dummies], axis=1)
print(“\n=== 変換後 ===”)
print(df)
# 平均満足度を計算
print(f”\n平均満足度: {df[‘satisfaction_score’].mean():.2f}”)
📝 STEP 9 のまとめ
✅ このステップで学んだこと
- カラム操作:追加(直接代入、assign)、削除(drop、del)、名前変更(rename)
- 条件分岐:loc[]、np.where()、np.select()
- 文字列操作:strip()、split()、replace()、contains()、extract()
- 日付処理:to_datetime()、.dt.year/.dt.month、日付計算
- カテゴリ変換:astype(‘category’)、ラベルエンコーディング、ワンホットエンコーディング
💡 データ変換のベストプラクティス
- 元データを残す:変換前のカラムは削除せず残しておく
- カラム名をわかりやすく:_normalized、_encoded など接尾辞をつける
- 処理の順序を考える:依存関係のある処理は順番に
- 変換後に確認:必ずhead()やdescribe()で確認
- エラーハンドリング:変換できない値がある場合を想定
🎯 次のステップの予告
次のSTEP 10では、「データ結合とマージ」を学びます。
- merge()(SQLのJOINと同様)
- concat()(縦横連結)
- join()(インデックスベース結合)
- 複数テーブルの結合戦略
📝 練習問題
問題 1
基礎
priceとquantityを掛け算してtotalカラムを追加してください。
【解答例】
df[‘total’] = df[‘price’] * df[‘quantity’]
問題 2
基礎
nameカラムの前後の空白を削除してください。
【解答例】
df[‘name’] = df[‘name’].str.strip()
問題 3
基礎
カラム名 ‘old_col’ を ‘new_col’ に変更してください。
【解答例】
df = df.rename(columns={‘old_col’: ‘new_col’})
問題 4
基礎
dateカラムを日付型に変換してください。
【解答例】
df[‘date’] = pd.to_datetime(df[‘date’])
問題 5
基礎
phoneカラムからハイフンを削除してください。
【解答例】
df[‘phone’] = df[‘phone’].str.replace(‘-‘, ”)
問題 6
基礎
不要なカラム ‘temp_col’ を削除してください。
【解答例】
df = df.drop(‘temp_col’, axis=1)
# または
df.drop(‘temp_col’, axis=1, inplace=True)
問題 7
応用
order_dateから年と月を抽出して、それぞれyear、monthカラムに追加してください。
【解答例】
df[‘order_date’] = pd.to_datetime(df[‘order_date’])
df[‘year’] = df[‘order_date’].dt.year
df[‘month’] = df[‘order_date’].dt.month
問題 8
応用
full_nameカラムをスペースで分割して、last_nameとfirst_nameカラムに分けてください。
【解答例】
df[[‘last_name’, ‘first_name’]] = df[‘full_name’].str.split(‘ ‘, expand=True)
問題 9
応用
categoryカラムをワンホットエンコーディングしてください。
【解答例】
dummies = pd.get_dummies(df[‘category’], prefix=’cat’)
df = pd.concat([df, dummies], axis=1)
問題 10
応用
ageカラムの値に基づいて、20歳未満を’未成年’、20歳以上を’成人’としてage_categoryカラムを作成してください(np.where使用)。
【解答例】
import numpy as np
df[‘age_category’] = np.where(df[‘age’] < 20, '未成年', '成人')
問題 11
応用
emailカラムから@より前のユーザー名を抽出してusernameカラムに格納してください。
【解答例】
df[‘username’] = df[‘email’].str.split(‘@’).str[0]
# または
df[‘username’] = df[‘email’].str.extract(r’^([^@]+)’, expand=False)
問題 12
応用
order_dateに3日を加算してdelivery_dateカラムを作成してください。
【解答例】
df[‘order_date’] = pd.to_datetime(df[‘order_date’])
df[‘delivery_date’] = df[‘order_date’] + pd.Timedelta(days=3)
問題 13
発展
scoreカラムの値に基づいて、90以上を’A’、70以上を’B’、50以上を’C’、50未満を’D’としてgradeカラムを作成してください(np.select使用)。
【解答例】
import numpy as np
conditions = [
df[‘score’] >= 90,
df[‘score’] >= 70,
df[‘score’] >= 50,
df[‘score’] < 50
]
choices = ['A', 'B', 'C', 'D']
df['grade'] = np.select(conditions, choices)
問題 14
発展
addressカラムから都道府県を抽出してprefectureカラムに格納してください(正規表現使用)。
【解答例】
df[‘prefecture’] = df[‘address’].str.extract(r'(.{2,3}[都道府県])’, expand=False)
問題 15
発展
以下の変換を一度に行ってください:
① dateカラムを日付型に変換
② yearとmonthを抽出
③ priceとquantityからtotalを計算
④ categoryをワンホットエンコーディング
【解答例】
import pandas as pd
# ① 日付型に変換
df[‘date’] = pd.to_datetime(df[‘date’])
# ② year と month を抽出
df[‘year’] = df[‘date’].dt.year
df[‘month’] = df[‘date’].dt.month
# ③ total を計算
df[‘total’] = df[‘price’] * df[‘quantity’]
# ④ category をワンホットエンコーディング
dummies = pd.get_dummies(df[‘category’], prefix=’cat’)
df = pd.concat([df, dummies], axis=1)
print(df)