機械学習データ前処理入門

機械学習データ前処理:行と列を入れ替えてデータを分析しやすい形にする方法【Pandas入門】

Tags: データ前処理, Pandas, データ整形, ピボット, 機械学習

データ前処理において、元のデータを分析や機械学習モデルの入力に適した形に「整形」することは非常に重要です。多くの場合、取得した生データはそのままでは分析しにくく、行と列を入れ替えたり、特定の列を基準にデータを組み替えたりする必要があります。

本記事では、Pythonのデータ分析ライブラリであるPandasを使用して、データの形を変更する基本的な手法を解説します。特に、ビジネスの現場でよく使われるExcelのピボットテーブルに近い操作や、複数の列に分散したデータを集約する操作に焦点を当て、コード例を交えながら丁寧に説明します。

なぜデータの「形」を変える必要があるのか

データ分析や機械学習モデルの構築を行う際、データがどのような「形」をしているかは、その後の作業効率や分析結果に大きく影響します。例えば、アンケートデータのように「人」が行に、「質問項目」が列になっているデータもあれば、時系列データのように「時間」が行に、「観測値」が列になっているデータもあります。

多くの分析手法や機械学習ライブラリは、特定のデータの形(構造)を前提としています。例えば、ある列が特定のカテゴリを表し、別の列がそれに対応する数値を表すような形式(ロング形式と呼ばれることがあります)が適している場合もあれば、各行が一つの観測データを示し、各列がその特徴量を示す形式(ワイド形式と呼ばれることがあります)が適している場合もあります。

元のデータを目的の形に変換することで、はじめて適切な分析手法を適用したり、モデルにデータを与えたりすることが可能になります。

Pandasでデータを整形する基本的な手法

Pandasには、データの形を変更するための強力な機能がいくつか備わっています。ここでは、特によく利用される pivot_tablemelt という2つの主要なメソッドを中心に解説します。

pivot_table: 横方向への集計・展開(Excelのピボットテーブルに似た操作)

pivot_table メソッドは、指定した列のユニークな値を新しい列(またはインデックス)として展開し、同時にデータを集計する機能を提供します。これは、Excelのピボットテーブルでよく行う操作に非常に似ています。

例えば、「日付」「店舗」「売上」のようなデータがあったときに、「日付」を行に、「店舗」を列に、「売上」を値として集計する、といったことが可能です。

具体的な例を見てみましょう。以下のような架空の売上データがあるとします。

import pandas as pd
import numpy as np

# サンプルデータの作成
data = {
    '日付': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02', '2023-01-01', '2023-01-02'],
    '店舗': ['A', 'B', 'A', 'C', 'C', 'B'],
    'カテゴリ': ['食品', '食品', '衣類', '食品', '衣類', '衣類'],
    '売上': [1000, 1500, 2000, 1200, 3000, 2500]
}
df = pd.DataFrame(data)

# 日付列をdatetime型に変換
df['日付'] = pd.to_datetime(df['日付'])

print("元のデータフレーム:")
print(df)
元のデータフレーム:
        日付 店舗 カテゴリ  売上
0 2023-01-01  A   食品  1000
1 2023-01-01  B   食品  1500
2 2023-01-02  A   衣類  2000
3 2023-01-02  C   食品  1200
4 2023-01-01  C   衣類  3000
5 2023-01-02  B   衣類  2500

このデータを、「日付」を行インデックス、「店舗」を列、「売上」を値として集計し、店舗ごとの日別売上を把握したいとします。pivot_table を使用すると、以下のように簡単に実現できます。

# pivot_tableを使用してデータを整形・集計
pivot_df = pd.pivot_table(
    df,
    values='売上',      # 値として使用する列
    index='日付',       # 新しい行インデックスにする列
    columns='店舗',     # 新しい列にする列
    aggfunc='sum',      # 集計方法(合計)
    fill_value=0        # 集計対象がなかった場合の欠損値を0で埋める
)

print("\npivot_tableで整形したデータフレーム:")
print(pivot_df)
pivot_tableで整形したデータフレーム:
店舗           A     B     C
日付                          
2023-01-01  1000  1500  3000
2023-01-02  2000  2500  1200

このように、pivot_table を使うことで、元のデータを行と列に展開し、同時に指定した方法で値を集計した新しいデータフレームを作成できます。aggfunc には 'mean' (平均) や 'count' (件数) など、さまざまな集計関数を指定できます。

melt: 縦方向への展開(複数の列を一つの列にまとめる)

melt メソッドは、複数の列に分散しているデータを、特定の識別子列に基づいて縦方向(ロング形式)に積み上げるように整形します。これは pivot_table とは逆の操作と考えることができます。

例えば、「年度」が行インデックスで、「地域Aの売上」「地域Bの売上」「地域Cの売上」が列になっているようなデータがあったときに、これを「年度」「地域」「売上」という3つの列を持つロング形式のデータに変換したい場合などに melt が役立ちます。

多くの統計モデルや機械学習ライブラリ、特にグラフ描画ライブラリ(Seabornなど)は、このようなロング形式のデータを入力として要求することが多いため、melt は非常に重要な整形手法です。

先ほどの pivot_table の結果として得られたデータフレームを、元の「日付」「店舗」「売上」のようなロング形式に戻してみましょう。

# meltを使用してデータを縦方向に展開
melted_df = pd.melt(
    pivot_df.reset_index(), # pivot_dfのインデックス(日付)を列に戻す
    id_vars='日付',       # 識別子としてそのまま残す列
    var_name='店舗',      # 展開した列名(店舗名)を格納する新しい列の名前
    value_name='売上'     # 展開した値(売上)を格納する新しい列の名前
)

print("\nmeltで整形したデータフレーム:")
print(melted_df)
meltで整形したデータフレーム:
        日付 店舗    売上
0 2023-01-01  A  1000
1 2023-01-02  A  2000
2 2023-01-01  B  1500
3 2023-01-02  B  2500
4 2023-01-01  C  3000
5 2023-01-02  C  1200

melt メソッドでは、id_vars で「そのまま残したい列」を指定し、それ以外の列が縦方向に積み上げられます。積み上げられた元の列名(この場合は店舗名 A, B, C)は var_name で指定した新しい列に、対応する値(この場合は売上)は value_name で指定した新しい列に格納されます。

注意点として、melt は集計を伴わないため、元の pivot_tablemelt しても必ずしも元の集計前のデータフレーム(この場合は df)と完全に同じ並びや形になるとは限りません。しかし、データの「ロング形式」という構造としては同じものになります。

まとめ

本記事では、Pandasを使ってデータの形を分析しやすいように変更する、基本的な整形方法を解説しました。

これらのデータの整形スキルは、その後のデータ分析や機械学習モデル構築の土台となります。取得したデータは必ずしも分析に適した形をしているわけではないため、今回ご紹介した pivot_tablemelt といった手法を活用して、データを適切な形に整えるプロセスを理解することは、データ前処理において非常に重要です。

データ前処理には様々なステップがありますが、データの形を理解し、必要に応じて整形することは、その後のステップを円滑に進めるための鍵となります。本記事が、皆様のデータ前処理スキルの向上の一助となれば幸いです。