Step 34:Pandasの総復習

🎓 ステップ34: Pandasの総復習

これまで学んだことを総まとめ!実践プロジェクトに挑戦しよう!

ステップ22からステップ33まで、Pandasの基礎から応用まで学んできました。今回は総復習として、これまでの内容を振り返りながら実践的な分析を行います。

📖 このステップで学ぶこと

・これまでの学習内容の振り返り

・総合演習問題

・ミニプロジェクト:売上データ分析

・よくあるエラーと対処法

🎯 1. これまでの学習内容の振り返り

Part 5(ステップ22〜28)とPart 6(ステップ29〜33)で学んだ内容を確認しましょう。

📘 Part 5:Pandas基礎編(ステップ22〜28)

📌 習得したスキル

ステップ 内容 主なメソッド
22 DataFrameの作成 pd.DataFrame(), pd.read_csv()
23 データの確認 head(), tail(), info(), describe()
24 データの抽出 loc[], iloc[], 条件抽出
25 データの並び替え sort_values(), sort_index()
26 欠損値の処理 isnull(), dropna(), fillna()
27 データ型の変換 astype(), to_numeric(), to_datetime()
28 基礎の総復習 総合演習

📘 Part 6:Pandas応用編(ステップ29〜33)

📌 習得したスキル

ステップ 内容 主なメソッド
29 グループ化と集計 groupby(), agg()
30 データの結合 merge(), concat()
31 データの加工と変換 apply(), str操作, dt操作
32 重複データの処理 duplicated(), drop_duplicates()
33 ピボットテーブル pivot_table(), crosstab()

📝 2. 総合演習問題

これまで学んだ内容を使って、実際のデータ分析を行います。

🔰 演習1:データ読み込みと確認

まずはサンプルデータを作成し、基本的な確認を行います。

コード:サンプルデータの作成

import pandas as pd
import numpy as np

# 乱数のシードを設定(毎回同じ結果になるように)
np.random.seed(42)

# サンプルデータ作成
sales_data = {
    '日付': pd.date_range('2024-01-01', periods=20, freq='D'),
    '商品ID': np.random.choice(['P001', 'P002', 'P003'], 20),
    '商品名': np.random.choice(['りんご', 'バナナ', 'みかん'], 20),
    '数量': np.random.randint(5, 20, 20),
    '単価': np.random.choice([100, 150, 80], 20),
    '地域': np.random.choice(['東京', '大阪', '名古屋'], 20)
}

df = pd.DataFrame(sales_data)
print("作成したデータ:")
print(df.head(10))

※ 画面が小さい場合は、コードブロックを横にスクロールできます

💡 コードの解説

np.random.seed(42)

 ・乱数の「種」を設定します

 ・これを設定すると、毎回同じ乱数が生成されます

 ・再現性のあるコードを書くために重要です

pd.date_range(‘2024-01-01′, periods=20, freq=’D’)

 ・2024年1月1日から20日分の日付を生成します

 ・freq=’D’は「毎日」という意味です

np.random.choice([‘P001’, ‘P002’, ‘P003’], 20)

 ・リストの中から20個をランダムに選びます

np.random.randint(5, 20, 20)

 ・5以上20未満の整数を20個生成します

実行結果

作成したデータ:
        日付  商品ID  商品名  数量  単価   地域
0 2024-01-01  P003  みかん  11  80   東京
1 2024-01-02  P002  バナナ  19  80   大阪
2 2024-01-03  P002  バナナ   6  80   大阪
3 2024-01-04  P001  りんご  14  80   東京
4 2024-01-05  P003  みかん   9  150  名古屋
5 2024-01-06  P001  りんご   7  100   大阪
6 2024-01-07  P003  みかん   9  100  名古屋
7 2024-01-08  P003  みかん  12  100  名古屋
8 2024-01-09  P003  みかん  17  150  名古屋
9 2024-01-10  P002  バナナ  12  100   東京

📝 データの基本情報を確認

コード:基本情報の確認

# 1. データの基本情報を確認
print("【データの基本情報】")
print(f"行数×列数: {df.shape}")
print(f"\n列名: {df.columns.tolist()}")
print(f"\nデータ型:")
print(df.dtypes)

# 2. 統計情報
print("\n【数値列の統計】")
print(df.describe())

※ 画面が小さい場合は、コードブロックを横にスクロールできます

💡 コードの解説

df.shape

 ・(行数, 列数)のタプルを返します

df.columns.tolist()

 ・列名をリスト形式で取得します

df.dtypes

 ・各列のデータ型を確認します

df.describe()

 ・数値列の統計情報(平均、標準偏差、最小、最大など)を表示

実行結果

【データの基本情報】
行数×列数: (20, 6)

列名: ['日付', '商品ID', '商品名', '数量', '単価', '地域']

データ型:
日付             datetime64[ns]
商品ID                  object
商品名                  object
数量                     int64
単価                     int64
地域                    object
dtype: object

【数値列の統計】
            数量         単価
count  20.000000    20.000000
mean   12.100000   102.500000
std     3.932417    26.915076
min     6.000000    80.000000
25%     9.000000    80.000000
50%    11.500000   100.000000
75%    14.250000   100.000000
max    19.000000   150.000000

📘 演習2:データクリーニングと加工

コード:データの加工

# 売上金額を計算(新しい列を追加)
df['売上金額'] = df['数量'] * df['単価']

# 日付から月と曜日を抽出
df['月'] = df['日付'].dt.month
df['曜日'] = df['日付'].dt.day_name()

# 週末フラグを追加
df['週末'] = df['曜日'].isin(['Saturday', 'Sunday'])

print("【加工後のデータ】")
print(df.head(10))

※ 画面が小さい場合は、コードブロックを横にスクロールできます

💡 コードの解説

df[‘売上金額’] = df[‘数量’] * df[‘単価’]

 ・数量と単価を掛け算して、新しい列「売上金額」を追加します

df[‘日付’].dt.month

 ・日付列から「月」を抽出します(.dtアクセサを使用)

df[‘日付’].dt.day_name()

 ・日付列から「曜日名」を英語で取得します

df[‘曜日’].isin([‘Saturday’, ‘Sunday’])

 ・曜日が土曜または日曜ならTrue、それ以外はFalse

実行結果

【加工後のデータ】
        日付  商品ID  商品名  数量  単価   地域  売上金額  月       曜日    週末
0 2024-01-01  P003  みかん  11  80   東京    880  1   Monday  False
1 2024-01-02  P002  バナナ  19  80   大阪   1520  1  Tuesday  False
2 2024-01-03  P002  バナナ   6  80   大阪    480  1 Wednesday False
3 2024-01-04  P001  りんご  14  80   東京   1120  1 Thursday  False
4 2024-01-05  P003  みかん   9 150  名古屋  1350  1   Friday  False
5 2024-01-06  P001  りんご   7 100   大阪    700  1 Saturday   True
6 2024-01-07  P003  みかん   9 100  名古屋   900  1   Sunday   True
7 2024-01-08  P003  みかん  12 100  名古屋  1200  1   Monday  False
8 2024-01-09  P003  みかん  17 150  名古屋  2550  1  Tuesday  False
9 2024-01-10  P002  バナナ  12 100   東京   1200  1 Wednesday False

📝 データ品質の確認

コード:重複と欠損値のチェック

# 重複チェック
duplicate_count = df.duplicated().sum()
print(f"重複データ: {duplicate_count}件")

# 欠損値チェック
print(f"\n欠損値の数:")
print(df.isnull().sum())

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

重複データ: 0件

欠損値の数:
日付      0
商品ID    0
商品名     0
数量      0
単価      0
地域      0
売上金額    0
月       0
曜日      0
週末      0
dtype: int64

📘 演習3:集計と分析

コード:商品ごとの売上集計

# 商品ごとの売上集計
print("【商品ごとの売上集計】")
product_summary = df.groupby('商品名').agg({
    '売上金額': ['sum', 'mean', 'count'],
    '数量': 'sum'
}).round(0)

print(product_summary)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

💡 コードの解説

df.groupby(‘商品名’)

 ・商品名ごとにデータをグループ化します

.agg({…})

 ・複数の列に対して、それぞれ異なる集計を行います

 ・売上金額には合計(sum)、平均(mean)、件数(count)を適用

 ・数量には合計(sum)を適用

.round(0)

 ・小数点以下を四捨五入します

実行結果

【商品ごとの売上集計】
        売上金額                  数量
          sum    mean count  sum
商品名                            
バナナ   4400.0  1100.0   4.0   44
みかん  10180.0  1131.0   9.0   95
りんご   6280.0   898.0   7.0   69

コード:地域ごとの売上集計

# 地域ごとの売上集計
print("【地域ごとの売上集計】")
region_summary = df.groupby('地域')['売上金額'].sum().sort_values(ascending=False)
print(region_summary)

# 週末と平日の売上比較
print("\n【週末vs平日の売上】")
weekend_summary = df.groupby('週末')['売上金額'].agg(['sum', 'mean', 'count'])
weekend_summary.index = ['平日', '週末']
print(weekend_summary)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

【地域ごとの売上集計】
地域
名古屋    9630
東京     6870
大阪     4360
Name: 売上金額, dtype: int64

【週末vs平日の売上】
       sum        mean  count
平日  19260  1071.111111     18
週末   1600   800.000000      2

📘 演習4:ピボットテーブル

コード:商品×地域のピボットテーブル

# 商品×地域のピボットテーブル
pivot = df.pivot_table(
    values='売上金額',
    index='商品名',
    columns='地域',
    aggfunc='sum',
    fill_value=0,
    margins=True,
    margins_name='合計'
)

print("【商品×地域の売上】")
print(pivot)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

【商品×地域の売上】
地域     名古屋    大阪    東京    合計
商品名                        
バナナ      0  2000  2400  4400
みかん   8000     0  2180 10180
りんご   1630  2360  2290  6280
合計    9630  4360  6870 20860

🚀 3. ミニプロジェクト:売上データ分析

ここからは、より実践的なデータ分析を行います。経営判断に役立つレポートを作成しましょう。

📌 分析の目的

・どの商品が売れているか?

・どの地域の売上が高いか?

・週末と平日で売上に差はあるか?

・売上トレンドは?

・改善すべき点は?

📘 ステップ1:データの準備

コード:分析用データの作成

import pandas as pd
import numpy as np

# データ作成
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='D')
products = ['りんご', 'バナナ', 'みかん', 'ぶどう', 'いちご']
regions = ['東京', '大阪', '名古屋', '福岡']

data = {
    '日付': np.random.choice(dates, 200),
    '商品名': np.random.choice(products, 200),
    '地域': np.random.choice(regions, 200),
    '数量': np.random.randint(1, 30, 200),
    '単価': np.random.choice([100, 150, 200, 250, 300], 200)
}

df = pd.DataFrame(data)

# 売上金額を計算
df['売上金額'] = df['数量'] * df['単価']

# 月と曜日を追加
df['月'] = df['日付'].dt.month
df['曜日'] = df['日付'].dt.day_name()
df['週末'] = df['曜日'].isin(['Saturday', 'Sunday'])

print("データの準備完了!")
print(f"データ件数: {len(df)}件")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

データの準備完了!
データ件数: 200件

📘 ステップ2:分析レポートの作成

コード:完全な分析レポート

print("="*60)
print("売上分析レポート")
print("="*60)

# 1. 全体サマリー
print("\n【1. 全体サマリー】")
print(f"分析期間: {df['日付'].min().date()} 〜 {df['日付'].max().date()}")
print(f"総売上: ¥{df['売上金額'].sum():,}")
print(f"取引件数: {len(df):,}件")
print(f"平均取引額: ¥{df['売上金額'].mean():,.0f}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

💡 コードの解説

df[‘日付’].min().date()

 ・最小の日付を取得し、.date()で日付部分だけ表示

f”¥{df[‘売上金額’].sum():,}”

 ・:,は3桁ごとにカンマを入れるフォーマット

 ・例:1234567 → 1,234,567

f”¥{df[‘売上金額’].mean():,.0f}”

 ・:,.0fは小数点以下0桁(整数)でカンマ付きフォーマット

コード:商品別・地域別の分析

# 2. 商品別ランキング
print("\n【2. 商品別売上ランキング】")
product_ranking = df.groupby('商品名').agg({
    '売上金額': 'sum',
    '数量': 'sum'
}).sort_values('売上金額', ascending=False)

# 構成比を追加
product_ranking['売上構成比(%)'] = (
    product_ranking['売上金額'] / product_ranking['売上金額'].sum() * 100
).round(1)

print(product_ranking)

# 3. 地域別分析
print("\n【3. 地域別売上ランキング】")
region_ranking = df.groupby('地域')['売上金額'].sum().sort_values(ascending=False)
print(region_ranking)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

【2. 商品別売上ランキング】
         売上金額  数量  売上構成比(%)
商品名                          
いちご   148150  542        22.5
バナナ   133700  573        20.3
ぶどう   132650  506        20.1
みかん   126700  614        19.2
りんご   117800  595        17.9

【3. 地域別売上ランキング】
地域
名古屋    175000
大阪     169800
東京     168950
福岡     145250
Name: 売上金額, dtype: int64

コード:週末vs平日、月別トレンド

# 4. 週末vs平日
print("\n【4. 週末vs平日の比較】")
weekend_analysis = df.groupby('週末').agg({
    '売上金額': ['sum', 'mean', 'count']
})
weekend_analysis.index = ['平日', '週末']
print(weekend_analysis)

# 5. 月別トレンド
print("\n【5. 月別売上推移】")
monthly_trend = df.groupby('月')['売上金額'].sum()
print(monthly_trend)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

【4. 週末vs平日の比較】
      売上金額                    
       sum         mean count
平日  467200  3233.103448   144
週末  191800  3425.000000    56

【5. 月別売上推移】
月
1    180250
2    176150
3    177450
4    125150
Name: 売上金額, dtype: int64

コード:分析結果と推奨アクション

# 6. 分析結果と推奨事項
print("\n【6. 分析結果と推奨事項】")

# 最も売れている商品
top_product = product_ranking.index[0]
print(f"✓ 最も売れている商品: {top_product}")

# 売上が最も高い地域
top_region = region_ranking.index[0]
print(f"✓ 売上が最も高い地域: {top_region}")

# 週末と平日の比較
weekend_avg = df[df['週末'] == True]['売上金額'].mean()
weekday_avg = df[df['週末'] == False]['売上金額'].mean()

if weekend_avg > weekday_avg:
    diff = ((weekend_avg / weekday_avg - 1) * 100)
    print(f"✓ 週末の売上が平日より{diff:.1f}%高い")
else:
    diff = ((weekday_avg / weekend_avg - 1) * 100)
    print(f"✓ 平日の売上が週末より{diff:.1f}%高い")

# 推奨アクション
print("\n【推奨アクション】")
bottom_product = product_ranking.index[-1]
print(f"1. {top_product}の在庫を増やす")
print(f"2. {top_region}での販促活動を強化")
print(f"3. {bottom_product}の販売戦略を見直す")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

実行結果

【6. 分析結果と推奨事項】
✓ 最も売れている商品: いちご
✓ 売上が最も高い地域: 名古屋
✓ 週末の売上が平日より5.9%高い

【推奨アクション】
1. いちごの在庫を増やす
2. 名古屋での販促活動を強化
3. りんごの販売戦略を見直す

⚠️ 4. よくあるエラーと対処法

Pandasを使っていると、様々なエラーに遭遇します。主なエラーと対処法を学びましょう。

🔴 エラー1:KeyError

🚨 エラー例

df['存在しない列名']

KeyError: '存在しない列名'

💡 原因と対処法

原因:指定した列名がDataFrameに存在しない

対処法:

 ・df.columnsで列名を確認する

 ・スペルミスがないかチェック

 ・全角・半角に注意(’売上’ と ‘売上’ は違う)

🔴 エラー2:ValueError

🚨 エラー例

df['数値列'].astype(int) で文字列が混じっている場合

ValueError: invalid literal for int()

💡 原因と対処法

原因:変換できない値が含まれている

対処法:

 ・pd.to_numeric(df['列'], errors='coerce')を使う

 ・errors=’coerce’で変換できない値をNaNにする

 ・事前にデータをクリーニング

🔴 エラー3:TypeError

🚨 エラー例

df['文字列列'].mean()

TypeError: Could not convert ... to numeric

💡 原因と対処法

原因:数値計算に文字列を使おうとした

対処法:

 ・df.dtypesでデータ型を確認

 ・数値列だけ選択:df.select_dtypes(include='number')

 ・型変換してから計算

🔴 エラー4:SettingWithCopyWarning

🚨 警告例

df_copy = df[df['売上'] > 1000]

df_copy['新しい列'] = 値

SettingWithCopyWarning

💡 原因と対処法

原因:コピーか参照かが曖昧

対処法:

 ・.copy()を使う:df_copy = df[条件].copy()

 ・または.locを使う

💡 5. Pandasの便利Tips

📘 Tip 1:チェーンメソッド

複数の処理を繋げて書くことで、コードを簡潔にできます。

コード:チェーンメソッドの例

# 複数の処理を繋げる
result = (df
    .query('売上金額 > 1000')          # 売上1000円以上を抽出
    .groupby('商品名')['売上金額']     # 商品名でグループ化
    .sum()                              # 合計を計算
    .sort_values(ascending=False)      # 降順でソート
    .head(5)                           # 上位5件を取得
)

print("売上1000円以上の商品TOP5:")
print(result)

※ 画面が小さい場合は、コードブロックを横にスクロールできます

📘 Tip 2:条件による値の設定

コード:np.whereとnp.select

# np.whereで条件分岐(2択)
df['売上区分'] = np.where(df['売上金額'] >= 2000, '高', '低')

# np.selectで複数条件(3択以上)
conditions = [
    df['売上金額'] >= 5000,
    df['売上金額'] >= 2000,
    df['売上金額'] < 2000
]
choices = ['特大', '大', '小']
df['売上ランク'] = np.select(conditions, choices)

print(df[['売上金額', '売上区分', '売上ランク']].head())

※ 画面が小さい場合は、コードブロックを横にスクロールできます

💡 np.where vs np.select

np.where(条件, True時の値, False時の値)

 ・2択の場合に使う(高/低、合格/不合格など)

np.select(条件リスト, 値リスト)

 ・3択以上の場合に使う(特大/大/小など)

📘 Tip 3:クイックプロファイリング

コード:データの概要を一度に確認

# データの概要を一度に確認
print("データ概要:")
print(f"形状: {df.shape}")
print(f"欠損値: {df.isnull().sum().sum()}個")
print(f"重複: {df.duplicated().sum()}行")
print(f"\n数値列の平均:")
print(df.select_dtypes(include='number').mean())

※ 画面が小さい場合は、コードブロックを横にスクロールできます

📝 最終チャレンジ問題

📋 総合演習問題

以下のデータについて、完全な分析レポートを作成してください:

1. データの読み込みと確認

2. データクリーニング(欠損値、重複、型変換)

3. 売上金額の計算

4. 商品別・地域別・期間別の集計

5. ピボットテーブルの作成

6. 分析結果のサマリー

import pandas as pd
import numpy as np

np.random.seed(100)
data = {
    '日付': pd.date_range('2024-01-01', periods=50, freq='D'),
    '商品名': np.random.choice(['りんご', 'バナナ', 'みかん', 'ぶどう', 'いちご'], 50),
    '数量': np.random.randint(5, 30, 50),
    '単価': np.random.choice([100, 150, 200, 250, 300], 50),
    '地域': np.random.choice(['東京', '大阪', '名古屋'], 50),
    '担当者': np.random.choice(['田中', '佐藤', '鈴木'], 50)
}

df = pd.DataFrame(data)

# ここから分析を始めてください!

※ 画面が小さい場合は、コードブロックを横にスクロールできます

解答例を見る

コード

import pandas as pd
import numpy as np

# データ作成
np.random.seed(100)
data = {
    '日付': pd.date_range('2024-01-01', periods=50, freq='D'),
    '商品名': np.random.choice(['りんご', 'バナナ', 'みかん', 'ぶどう', 'いちご'], 50),
    '数量': np.random.randint(5, 30, 50),
    '単価': np.random.choice([100, 150, 200, 250, 300], 50),
    '地域': np.random.choice(['東京', '大阪', '名古屋'], 50),
    '担当者': np.random.choice(['田中', '佐藤', '鈴木'], 50)
}

df = pd.DataFrame(data)

print("="*60)
print("売上データ完全分析レポート")
print("="*60)

# 1. データの確認
print("\n【1. データの基本情報】")
print(f"期間: {df['日付'].min().date()} 〜 {df['日付'].max().date()}")
print(f"データ件数: {len(df)}件")
print(f"欠損値: {df.isnull().sum().sum()}個")
print(f"重複: {df.duplicated().sum()}行")

# 2. 売上金額の計算
df['売上金額'] = df['数量'] * df['単価']
print(f"\n総売上: ¥{df['売上金額'].sum():,}")

# 3. 商品別集計
print("\n【2. 商品別売上ランキング】")
product_sales = df.groupby('商品名').agg({
    '売上金額': 'sum',
    '数量': 'sum'
}).sort_values('売上金額', ascending=False)
print(product_sales)

# 4. 地域別集計
print("\n【3. 地域別売上】")
region_sales = df.groupby('地域')['売上金額'].sum().sort_values(ascending=False)
print(region_sales)

# 5. ピボットテーブル
print("\n【4. 商品×地域のクロス分析】")
pivot = df.pivot_table(
    values='売上金額',
    index='商品名',
    columns='地域',
    aggfunc='sum',
    fill_value=0,
    margins=True,
    margins_name='合計'
)
print(pivot)

# 6. サマリー
print("\n【5. 分析サマリー】")
print(f"✓ 最も売れた商品: {product_sales.index[0]}")
print(f"✓ 売上が最も高い地域: {region_sales.index[0]}")
print(f"✓ 平均取引額: ¥{df['売上金額'].mean():,.0f}")

※ 画面が小さい場合は、コードブロックを横にスクロールできます

🎯 このステップのまとめ

🎉 おめでとうございます!

Pandas基礎・応用編を完了しました!

これでデータ分析の基本的なスキルが身につきました。

✅ DataFrameの操作

✅ データクリーニング

✅ 集計と分析

✅ データ結合

✅ ピボットテーブル

✅ 実践的なデータ分析

🚀 次のステップ

Part 7:データ可視化で、グラフを作成して分析結果を視覚的に表現する方法を学びます!

・Matplotlib:グラフの基本

・様々なグラフ:折れ線、棒、円、散布図

・グラフの装飾:タイトル、ラベル、凡例

❓ よくある質問

Q1: どのくらい練習すれば使いこなせますか?

A: 個人差がありますが、毎日1時間×1ヶ月ほど実際のデータで練習すると、基本的な分析はできるようになります。重要なのは継続です。

Q2: エラーが出たときはどうすればいいですか?

A: 以下の手順で解決しましょう:

1. エラーメッセージをよく読む

2. Google検索する(エラーメッセージをそのまま検索)

3. Stack Overflowで同じエラーを探す

4. 公式ドキュメントを確認

エラーは学習のチャンスです!

Q3: 次に学ぶべきことは?

A: おすすめの学習順序:

1. データ可視化(Matplotlib, Seaborn)

2. 機械学習の基礎(scikit-learn)

3. 統計学の基礎

4. SQLとの連携

Q4: おすすめの練習データはありますか?

A:

Kaggle Datasets:様々な分野のデータ

政府統計:e-Stat(日本の統計)

UCI Machine Learning Repository

自分で集めたデータ:最も学習効果が高い!

📝

学習メモ

Pythonデータ分析入門 - Step 34

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE