pandasで二重ヘッダー(double header)を扱う方法!データフレーム操作のテクニック

こんにちは、今回はpandasで二重ヘッダー(double header)を扱う方法について解説します。

はじめに

二重ヘッダーとは、表の列または行に複数のレベルを持つヘッダーのことです。例えば、下記のような表がある場合、”Year”と”Month”が1つのレベル、”Temperature”と”Rainfall”がもう1つのレベルとなります。

|     | Temperature | Rainfall |
|-----|-------------|----------|
|Year | Month       |          |
|     | Jan | Feb   | Jan      |
|-----|-----|-------|----------|
|2019 | 3   | 4     | 10       |
|2020 | 4   | 5     | 9        |

このような表を扱う場合、pandasのデータフレームを使うと便利です。データフレームを扱うことで、二重ヘッダーの表のデータを簡単に操作できます。

二重ヘッダー(double header)の概要とpandasでの扱い方

二重ヘッダーの表は、pandasのデータフレームによって扱うことができます。データフレームの列または行に、二重ヘッダーを設定することができます。

データフレームの列に二重ヘッダーを設定する場合、以下のように列のヘッダーをタプルで指定します。

import pandas as pd
# 二重ヘッダーを持つデータの例
data = [
[3, 4, 10],
[4, 5, 9]
]
columns = [("Temperature", "Jan"), ("Temperature", "Feb"), ("Rainfall", "Jan")]
index = [2019, 2020]
# データフレームの作成
df = pd.DataFrame(data, index=index, columns=columns)
print(df)

上記のコードでは、データフレームの列に二重ヘッダーを設定しています。”Temperature”と”Rainfall”が1つのレベル、”Jan”と”Feb”がもう1つのレベルとなっています。

また、データフレームの行に二重ヘッダーを設定する場合は、以下のように行のヘッダーをタプルで指定します。

import pandas as pd
# 二重ヘッダーを持つデータの例
data = [
    [3, 4, 10],
    [4, 5, 9],
    [4, 5, 9]
]
columns = ["Jan", "Feb", "Jan"]
index = [("Temperature", 2019), ("Temperature", 2020), ("Rainfall", 2020)]
# データフレームの作成
df = pd.DataFrame(data, index=index, columns=columns)
print(df)

上記のコードでは、データフレームの行に二重ヘッダーを設定しています。”Temperature”と”Rainfall”が1つのレベル、2019と2020がもう1つのレベルとなっています。

二重ヘッダーを含むデータの読み込み方法

二重ヘッダーを含むデータを読み込む場合は、pandasのread_csv関数を使います。読み込むCSVファイルにヘッダーが含まれている場合、header=[0,1]と指定することで二重ヘッダーを読み込むことができます。

例えば、以下のようなCSVファイルがある場合、

,Temperature,,Rainfall,
Year,Month,Jan,Feb,Jan
2019,3,4,10,
2020,4,5,9,

以下のコードで二重ヘッダーを含むデータを読み込むことができます。

import pandas as pd
# CSVファイルの読み込み
df = pd.read_csv("data.csv", header=[0,1])
print(df)

上記のコードでは、read_csv関数のheader=[0,1]で二重ヘッダーを読み込んでいます。

二重ヘッダーのデータフレーム操作の基本

二重ヘッダーのデータフレームを操作する場合、以下のような方法があります。

列または行の選択

二重ヘッダーのデータフレームから、特定の列または行を選択する場合、以下のようにタプルで指定します。

import pandas as pd
# 二重ヘッダーを持つデータの例
data = [
[3, 4, 10],
[4, 5, 9]
]
columns = [("Temperature", "Jan"), ("Temperature", "Feb"), ("Rainfall", "Jan")]
index = [2019, 2020]
# データフレーム
df = pd.DataFrame(data, index=index, columns=columns)
# 列の選択
print(df[("Temperature", "Jan")])
# 行の選択
print(df.loc[2019])

上記のコードでは、列の”Temperature”と”Jan”、行の2019をそれぞれ選択しています。

列または行の追加・削除

二重ヘッダーのデータフレームから、列または行を追加・削除する場合、以下のように列または行のヘッダーをタプルで指定します。

import pandas as pd
# 二重ヘッダーを持つデータの例
data = [
[3, 4, 10],
[4, 5, 9]
]
columns = [("Temperature", "Jan"), ("Temperature", "Feb"), ("Rainfall", "Jan")]
index = [2019, 2020]
# データフレームの作成
df = pd.DataFrame(data, index=index, columns=columns)
# 列の追加
df[("Rainfall", "Feb")] = [8, 7]
# 行の追加
df.loc[2021] = [6, 7, 8, 9]
# 列の削除
df = df.drop(("Rainfall", "Jan"), axis=1)
# 行の削除
df = df.drop(2020)
print(df)

上記のコードでは、列の(“Rainfall”, “Feb”)と行の2021を追加、列の(“Rainfall”, “Jan”)と行の2020を削除しています。

実践例: 二重ヘッダーを扱う具体的な処理方法

実際に二重ヘッダーのデータを扱う例として、以下のような表を考えます。

|       | Math           | Science        |
|-------|----------------|----------------|
|       | Average | Max   | Average | Max   |
| Alice | 80      | 95    | 85      | 92    |
| Bob   | 75      | 90    | 82      | 88    |
| Chris | 90      | 100   | 78      | 85    |

この表は、3人の生徒の数学と理科の成績を示しています。列には、”Math”と”Science”という2つの科目があり、更に”Average”と”Max”という2つのレベルがあります。行には、3人の生徒の名前があります。

この表を読み込んで、以下の処理を行います。

  • 各生徒の数学と理科の平均点を計算する
  • 各生徒の数学と理科の最高点を計算する
  • 数学の平均点が80以上の生徒の名前を表示する

以下のコードで、上記の処理を行います。

import pandas as pd
# データの準備
data = [
[80, 95, 85, 92],
[75, 90, 82, 88],
[90, 100, 78, 85]
]
columns = pd.MultiIndex.from_product([["Math", "Science"], ["Average", "Max"]])
index = ["Alice", "Bob", "Chris"]
# データフレームの作成
df = pd.DataFrame(data, index=index, columns=columns)
print("=== Original Data ===")
print(df)
# 数学と理科の平均点を計算する
df_mean = df.mean(level=0, axis=1)
df_mean.columns = ["Math Mean", "Science Mean"]
print("=== Mean Scores ===")
print(df_mean)
# 数学と理科の最高点を計算する
df_max = df.max(level=0, axis=1)
df_max.columns = ["Math Max", "Science Max"]
print("=== Max Scores ===")
print(df_max)
# 数学の平均点が80以上の生徒の名前を表示する
math_mean_above_80 = df_mean[df_mean["Math Mean"] >= 80].index.tolist()
print("=== Math Mean Above 80 ===")
print(math_mean_above_80)

上記のコードでは、まずデータを準備し、MultiIndex.from_productで二重ヘッダーを作成しています。次に、数学と理科の平均点を計算し、mean関数で各生徒ごとに平均値を計算しています。同様に、最高点を計算し、max関数で各生徒ごとに最高点を計算しています。最後に、数学の平均点が80以上の生徒の名前を表示しています。

まとめ

今回は、pandasで二重ヘッダー(double header)を扱う方法について解説しました。pandasのデータフレームを使うことで、二重ヘッダーの表のデータを簡単に操作できることがわかりました。また、実際のデータを使って、二重ヘッダーのデータフレーム操作の基本的な方法を紹介しました。

二重ヘッダーを扱う場合には、列または行のヘッダーをタプルで指定することが必要であることに注意しましょう。また、read_csv関数を使って、二重ヘッダーを含むデータを簡単に読み込むことができます。