1. Pandasの基本
Pandasは、Pythonでデータ分析を行うための強力なライブラリです。DataFrameとSeriesという2つの主要なデータ構造を提供し、大量のデータを効率的に処理できます。まずは、50件のサンプルデータを作成し、基本的な操作を見ていきましょう。
import pandas as pd
import numpy as np
# 50件のサンプルデータを作成
np.random.seed(0)
data = {
'名前': [f'社員{i}' for i in range(1, 51)],
'年齢': np.random.randint(22, 60, 50),
'部署': np.random.choice(['営業', '技術', '人事', '経理'], 50),
'給与': np.random.randint(300000, 800000, 50),
'勤続年数': np.random.randint(0, 30, 50)
}
df = pd.DataFrame(data)
print(df.head())
2. データの基本情報の取得
データフレームの基本情報を取得することは、データ分析の第一歩です。行数、列数、データ型、欠損値の有無などを確認しましょう。
# データフレームの基本情報を表示
print(df.info())
# 統計情報を表示
print(df.describe())
# 欠損値の確認
print(df.isnull().sum())
3. データの選択と抽出
Pandasでは、様々な方法でデータを選択・抽出できます。インデックス、列名、条件式などを使って必要なデータにアクセスする方法を学びましょう。
# 特定の列を選択
print(df['年齢'])
# 複数の列を選択
print(df[['名前', '部署', '給与']])
# 条件に基づいて行を選択
print(df[df['年齢'] > 40])
# locを使用して行と列を選択
print(df.loc[0:5, ['名前', '給与']])
# ilocを使用してインデックスで選択
print(df.iloc[0:5, 1:3])
4. データの集計と要約
データの集計は分析の重要な部分です。グループ化や集計関数を使って、データの要約統計量を計算する方法を見ていきます。
# 部署ごとの平均給与を計算
print(df.groupby('部署')['給与'].mean())
# 部署ごとの年齢の最小値、最大値、平均値を計算
print(df.groupby('部署')['年齢'].agg(['min', 'max', 'mean']))
# 部署と年齢層でグループ化し、給与の平均を計算
df['年齢層'] = pd.cut(df['年齢'], bins=[0, 30, 40, 50, 100], labels=['20代', '30代', '40代', '50代以上'])
print(df.groupby(['部署', '年齢層'])['給与'].mean().unstack())
5. データの変換と整形
データ分析では、元のデータを変換したり整形したりする必要がしばしばあります。列の追加、データ型の変換、欠損値の処理などの方法を学びましょう。
# 新しい列を追加(ボーナス = 給与の10%)
df['ボーナス'] = df['給与'] * 0.1
# データ型の変換(給与を文字列に)
df['給与_文字列'] = df['給与'].astype(str)
# 欠損値の挿入と処理
df.loc[0:5, '勤続年数'] = np.nan
df['勤続年数'] = df['勤続年数'].fillna(df['勤続年数'].mean())
print(df.head(10))
6. データのソートと並べ替え
データを特定の列に基づいてソートすることで、傾向や外れ値を見つけやすくなります。複数の列を使った高度なソートも可能です。
# 給与で降順にソート
print(df.sort_values('給与', ascending=False).head())
# 部署でソートし、さらに給与で降順にソート
print(df.sort_values(['部署', '給与'], ascending=[True, False]).head(10))
# インデックスでソート
df_shuffled = df.sample(frac=1) # データをシャッフル
print(df_shuffled.sort_index().head())
7. データのマージと結合
複数のデータフレームを組み合わせることで、より豊富な情報を得ることができます。様々な結合方法を使って、データを統合する方法を見ていきましょう。
# 新しいデータフレームを作成(部署ごとの予算)
budget_data = {
'部署': ['営業', '技術', '人事', '経理'],
'予算': [10000000, 15000000, 5000000, 8000000]
}
df_budget = pd.DataFrame(budget_data)
# 内部結合
df_merged = pd.merge(df, df_budget, on='部署')
# 外部結合
df_outer = pd.merge(df, df_budget, on='部署', how='outer')
print(df_merged.head())
print(df_outer.head())
8. 時系列データの処理
Pandasは時系列データの処理に強みを持っています。日付や時刻のデータを扱う方法、リサンプリング、移動平均の計算などを学びましょう。
# 日付インデックスを持つデータフレームを作成
dates = pd.date_range('2023-01-01', periods=50, freq='D')
ts_data = pd.DataFrame({'値': np.random.randn(50)}, index=dates)
# 月次データにリサンプリング
monthly_data = ts_data.resample('M').mean()
# 7日間の移動平均を計算
rolling_mean = ts_data.rolling(window=7).mean()
print(ts_data.head())
print(monthly_data)
print(rolling_mean.head(10))
9. ピボットテーブルとクロス集計
ピボットテーブルとクロス集計は、データを再構成して新しい洞察を得るのに役立ちます。複雑なデータの要約を簡単に作成できます。
# ピボットテーブルの作成
pivot_table = pd.pivot_table(df, values='給与', index='部署', columns='年齢層', aggfunc='mean')
# クロス集計
cross_tab = pd.crosstab(df['部署'], df['年齢層'])
print(pivot_table)
print(cross_tab)
10. データの可視化
Pandasは、Matplotlibと連携して簡単にデータを可視化できます。基本的なグラフの作成方法を見ていきましょう。
import matplotlib.pyplot as plt
# 棒グラフ:部署ごとの平均給与
df.groupby('部署')['給与'].mean().plot(kind='bar')
plt.title('部署別平均給与')
plt.show()
# 散布図:年齢と給与の関係
plt.figure(figsize=(10, 6))
plt.scatter(df['年齢'], df['給与'])
plt.xlabel('年齢')
plt.ylabel('給与')
plt.title('年齢と給与の関係')
plt.show()
11. 高度なデータ操作:apply と applymap
apply
とapplymap
メソッドを使用すると、データフレームやシリーズに対してカスタム関数を適用できます。これにより、複雑なデータ変換や計算が可能になります。
# 給与に基づいて等級を付ける関数
def salary_grade(salary):
if salary < 400000:
return 'C'
elif salary < 600000:
return 'B'
else:
return 'A'
# apply を使用して新しい列を作成
df['給与等級'] = df['給与'].apply(salary_grade)
# applymap を使用してデータフレーム全体に関数を適用
df_normalized = df[['年齢', '給与', '勤続年数']].applymap(lambda x: (x - x.mean()) / x.std())
print(df[['名前', '給与', '給与等級']].head(10))
print(df_normalized.head())
12. 欠損値の高度な処理
実際のデータセットでは、欠損値の処理が重要になります。単純な削除や平均値での補完以外にも、様々な方法があります。
# 意図的に欠損値を作成
df.loc[0:10, '給与'] = np.nan
df.loc[20:25, '年齢'] = np.nan
# 前方補完
df['給与_前方補完'] = df['給与'].fillna(method='ffill')
# 線形補間
df['年齢_補間'] = df['年齢'].interpolate()
# 多重代入法(簡易版)
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean')
df_imputed = pd.DataFrame(imputer.fit_transform(df[['年齢', '給与']]), columns=['年齢_imputed', '給与_imputed'])
print(df[['給与', '給与_前方補完']].head(15))
print(df[['年齢', '年齢_補間']].head(30))
print(df_imputed.head())
13. 高度なグループ操作
グループ化されたデータに対して、より複雑な操作を行う方法を見ていきます。カスタム集計関数の適用や、グループ内での相対的な計算などが可能です。
# カスタム集計関数
def top_3_avg(x):
return x.nlargest(3).mean()
# グループごとに複数の集計を実行
advanced_agg = df.groupby('部署').agg({
'給与': ['mean', 'median', top_3_avg],
'年齢': ['min', 'max', 'std']
})
# グループ内での相対的な計算
df['給与_部署内相対'] = df.groupby('部署')['給与'].transform(lambda x: (x - x.mean()) / x.std())
print(advanced_agg)
print(df[['名前', '部署', '給与', '給与_部署内相対']].head(10))
14. 時系列データの高度な分析
時系列データに対して、より高度な分析手法を適用します。季節性の分解、自己相関の計算、移動相関などを行います。
import pandas as pd
import numpy as np
from statsmodels.tsa.seasonal import seasonal_decompose
import matplotlib.pyplot as plt
# より長い時系列データを生成
dates = pd.date_range('2020-01-01', periods=730, freq='D')
ts = pd.Series(np.random.randn(730).cumsum() + 20 + np.sin(np.arange(730) * 2 * np.pi / 365) * 10, index=dates)
# 季節性分解
result = seasonal_decompose(ts, model='additive', period=365)
# プロット
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, figsize=(12, 16))
result.observed.plot(ax=ax1)
ax1.set_title('Observed')
result.trend.plot(ax=ax2)
ax2.set_title('Trend')
result.seasonal.plot(ax=ax3)
ax3.set_title('Seasonal')
result.resid.plot(ax=ax4)
ax4.set_title('Residual')
plt.tight_layout()
plt.show()
# 自己相関
from pandas.plotting import autocorrelation_plot
autocorrelation_plot(ts)
plt.show()
# 移動相関
ts2 = ts.shift(30) + np.random.randn(730) * 5
rolling_corr = ts.rolling(window=90).corr(ts2)
rolling_corr.plot()
plt.title('90日移動相関')
plt.show()
15. 高度なインデックス操作とマルチインデックス
Pandasの高度な機能の一つとして、複雑なインデックス操作とマルチインデックスの使用があります。これらを活用することで、より柔軟なデータ分析が可能になります。
# マルチインデックスの作成
multi_index = pd.MultiIndex.from_product([['営業', '技術', '人事', '経理'], ['正社員', '契約社員']], names=['部署', '雇用形態'])
df_multi = pd.DataFrame(np.random.randn(8, 3), index=multi_index, columns=['売上', '経費', '利益'])
# レベル別の集計
print(df_multi.groupby(level='部署').mean())
print(df_multi.groupby(level='雇用形態').mean())
# インデックスのリセットとセット
df_reset = df_multi.reset_index()
print(df_reset.head())
df_set = df_reset.set_index(['部署', '雇用形態'])
print(df_set.head())
# クロスセクション選択
print(df_multi.xs('正社員', level='雇用形態'))
# インデックス名の変更
df_multi.index.names = ['Division', 'EmploymentType']
print(df_multi.head())
まとめ
この記事では、Pandasの高度な使い方について15の章にわたって詳しく解説しました。主な内容は以下の通りです:
- Pandasの基本と50件のサンプルデータの作成
- データの基本情報の取得方法
- データの選択と抽出テクニック
- データの集計と要約統計量の計算
- データの変換と整形手法
- データのソートと並べ替え
- 複数のデータフレームのマージと結合
- 時系列データの処理方法
- ピボットテーブルとクロス集計の作成
- Pandasを使用したデータの可視化
- apply と applymap を使用した高度なデータ操作
- 欠損値の高度な処理方法
- グループ化されたデータに対する複雑な操作
- 時系列データの高度な分析テクニック
- 高度なインデックス操作とマルチインデックスの使用
これらの技術を習得することで、より効率的で洞察力のあるデータ分析が可能になります。Pandasは非常に強力なライブラリであり、これらの高度な機能を使いこなすことで、複雑なデータ処理タスクも簡単に実行できるようになります。
データ分析の実践では、ここで紹介した技術を組み合わせて使用することが多いでしょう。例えば、データの前処理として欠損値を処理し、必要な特徴量を抽出した後、グループ化して集計を行い、最後に結果を可視化するといった流れです。
Pandasの機能を十分に活用することで、データからより多くの価値を引き出し、より良い意思決定につなげることができます。継続的な学習と実践を通じて、Pandasのスキルを磨いていくことをお勧めします。