Pynote

Python、機械学習、画像処理について

pandas - melt() でデータフレームを横持ちから縦持ちに変換する。

概要

pandas の melt() でデータフレームを横持ちから縦持ちに変換する方法を紹介する。

横持ち、縦持ち

各変数ごとに列を持つテーブル形式を横持ち (wide format) という。
一方、変数名を表す列と値を表す列を持つテーブル形式を縦持ち (long format) という。
横持ちのテーブルを縦持ちのテーブルに変換することを pivot、その逆を unpivot という。
データ処理の観点からテーブルは縦持ちにしておくことが好ましい。


melt() - 横持ちから縦持ちに変換する。(unpivot)

pandas.melt でデータフレームを横持ちから縦持ちに変換できる (unpivot)。
id_vars には、unpivot の対象にしない列名を指定する。
value_vars には、unpivot の対象にする列名を指定する。
var_name は変数名を表す列名、value_name は値を表す列名を指定する。

pandas.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)

データフレームを用意する。

列が場所、緯度、経度、1月~3月の平均気温となっている。

import pandas as pd

df = pd.DataFrame({'場所': ['東京', '名古屋', '大阪'],
                   '緯度': [35, 35, 34],
                   '経度': [139, 136, 135],
                   '2019/01': [5, 9, 8],
                   '2019/02': [8, 6, 7],
                   '2019/03': [5, 5, 8]},
                  columns=['場所', '緯度', '経度', '2019/01', '2019/02', '2019/03'])

場所 緯度 経度 2019/01 2019/02 2019/03
0 東京 35 139 5 8 5
1 名古屋 35 136 9 6 5
2 大阪 34 135 8 7 8

横持ちから縦持ちに変換する。(unpivot)

場所、緯度、経度は unpivot の対象でないので、id_vars に指定する。
それ以外の 2019/01、2019/02、2019/03 の3列が unpivot の対象である。
value_vars を明示的に指定しない場合は、id_vars 以外の列がすべて unpivot の対象となる仕様なので、value_vars は指定しないでおく。
変数は年月、値は気温を表すので、それを列名にするため var_name、value_name でそれぞれ指定している。

df2 = df.melt(id_vars=['場所', '緯度', '経度'],
              var_name='年月', value_name='平均気温')

場所 緯度 経度 年月 平均気温
0 東京 35 139 2019/01 5
1 名古屋 35 136 2019/01 9
2 大阪 34 135 2019/01 8
3 東京 35 139 2019/02 8
4 名古屋 35 136 2019/02 6
5 大阪 34 135 2019/02 7
6 東京 35 139 2019/03 5
7 名古屋 35 136 2019/03 5
8 大阪 34 135 2019/03 8