如何从pandas DataFrame中“反转”特定列?
我有一个 pandas 的数据表,比如:
df = pd.DataFrame({'farm' : ['A','B','A','B'],
'fruit':['apple','apple','pear','pear'],
'2014':[10,12,6,8],
'2015':[11,13,7,9]})
也就是说:
2014 2015 farm fruit
0 10 11 A apple
1 12 13 B apple
2 6 7 A pear
3 8 9 B pear
我该怎么把它转换成下面这个样子呢?
farm fruit value year
0 A apple 10 2014
1 B apple 12 2014
2 A pear 6 2014
3 B pear 8 2014
4 A apple 11 2015
5 B apple 13 2015
6 A pear 7 2015
7 B pear 9 2015
我试过 stack
和 unstack
,但是没能成功。
2 个回答
2
可以使用 stack()
来实现;不过要先调用 set_index()
,这样才能为每一对年份和数值重复 farm
和 fruit
。
long_df = df.set_index(['farm', 'fruit']).rename_axis(columns='year').stack().reset_index(name='value')
另外,melt
也是一个 DataFrame 的方法,可以这样调用:
long_df = df.melt(id_vars=['farm', 'fruit'], var_name='year', value_name='value')
还有一个有趣的函数是 pd.wide_to_long
,它也可以用来“融化”一个数据框。不过它需要一个 stubname
,所以在这个问题的情况下不适用,但在其他情况下可以使用。例如,下面的例子中(注意列标签中的年份有 value_
)。
long_df = pd.wide_to_long(df, 'value', i=['farm', 'fruit'], j='year', sep='_').reset_index()
47
这可以通过 pd.melt()
来实现:
# value_name is 'value' by default, but setting it here to make it clear
pd.melt(x, id_vars=['farm', 'fruit'], var_name='year', value_name='value')
结果:
farm fruit year value
0 A apple 2014 10
1 B apple 2014 12
2 A pear 2014 6
3 B pear 2014 8
4 A apple 2015 11
5 B apple 2015 13
6 A pear 2015 7
7 B pear 2015 9
[8 rows x 4 columns]
我不太确定“melt”这个名字在这种操作中有多常见,但在R语言的 reshape2
包里就是这么叫的,可能是这里名字的来源。