前処理大全の第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を使うことで、アンピボットが楽にできます。
コメント