python/Rで縦持ちのデータを横持ちにする

スポンサーリンク
Python
スポンサーリンク

前処理大全の第7章の展開では、縦持ちから横持ちのawesomeな方法が記載されていましたが、逆の横持ちから縦持ちへの言及がありませんでした。このような手法は、あまり多用されていないから記載がなかったのかもしれません。

今回、仕事で横持ちから縦持ちにする必要がでてきたので調べてみました。

 

スポンサーリンク

利用したサンプルデータ

年月日が横持ちになっているテーブルを、年月日をdate、qtyに数字を入れて、縦持ちにする方法です。横持ちテーブルの年月日にある数字はqtyとします。

 

(before)横持ちテーブル

id name 20170401 20170501 20170601
001 sato 10 20 30
002 kondo 100 200 300

 

(after)縦持ちテーブル

id name date qty
001 sato 20170401 10
001 sato 20170501 20
001 sato 20170601 30
002 kondo 20170401 100
002 kondo 20170501  200 
002 kondo 20170601  300 

 

python編

アンピボット(横持ちから縦持ちにすること)は、pandas.meltを利用しました。

公式ドキュメントはこちらです。

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.melt.html

 

import pandas as pd
qty_df = pd.read_table('~/Desktop/analysis/blog/input/yoko.csv')
qty_df
id name 20170401 20170501 20170601
0 1 sato 10 20 30
1 2 kondo 100 200 300
# melt : データフレームをアンピボットする
# qty_df : データフレーム
# id_vars=['id', 'name'] : アンピボットしない列名
# var_name='date' : アンピボット対象の列名をセットする列名
# value_name='qty' : アンピボット対象の値をセットする列名
qty_df_T = pd.melt(qty_df, id_vars=['id', 'name'], var_name='date', value_name='qty')
qty_df_T
id name date qty
0 1 sato 20170401 10
1 2 kondo 20170401 100
2 1 sato 20170501 20
3 2 kondo 20170501 200
4 1 sato 20170601 30
5 2 kondo 20170601 300
# csvで出力
qty_df_T.to_csv('qty.csv')

 

R編

アンピボットは、gatherを利用しました。

公式ドキュメントはこちらです。

gather function - RDocumentation
Gather takes multiple columns and collapses into key-value pairs, duplicating all other columns as needed. You use gather() when you notice that you have column...

 

library('tidyr')
library('dplyr')
df = read.table(file = '~/Desktop/analysis/blog/input/yoko.csv', header = TRUE)
df
id name X20170401 X20170501 X20170601
1 sato 10 20 30
2 kondo 100 200 300
# df : data.frame
# gather : データフレームをアンピボットする関数
# key = date : アンピボット対象の列名をセットする列名
# value = qty : アンピボット対象の値をセットする列名
# X20170401:X20170601 : アンピボットする列名
df.gather <- df %>%
                        tidyr::gather( key = date, value = qty, X20170401:X20170601)
df.gather
id name date qty
1 sato X20170401 10
2 kondo X20170401 100
1 sato X20170501 20
2 kondo X20170501 200
1 sato X20170601 30
2 kondo X20170601 300
# パイプを利用しない方法
tidyr::gather( df, key = date, value = qty, X20170401:X20170601)
id name date qty
1 sato X20170401 10
2 kondo X20170401 100
1 sato X20170501 20
2 kondo X20170501 200
1 sato X20170601 30
2 kondo X20170601 300

 

まとめ

Pythonではpandasのmelt、Rではgatherを使うことで、アンピボットが楽にできます。

 

 

コメント

タイトルとURLをコピーしました