Python Pandas中的R dcast等价功能
我想在Python中实现下面这些命令的效果:
test <- data.frame(convert_me=c('Convert1','Convert2','Convert3'),
values=rnorm(3,45, 12), age_col=c('23','33','44'))
test
library(reshape2)
t <- dcast(test, values ~ convert_me+age_col, length )
t
也就是说,这个:
convert_me values age_col
Convert1 21.71502 23
Convert2 58.35506 33
Convert3 60.41639 44
变成这个:
values Convert2_33 Convert1_23 Convert3_44
21.71502 0 1 0
58.35506 1 0 0
60.41639 0 0 1
我知道通过使用一些临时变量,我可以获取列的值并把它们转化为列名,但有没有什么简单的方法可以像R那样把它们合并在一起呢?
2 个回答
3
我们可以使用 pd.get_dummies
这个函数。在现在的 pandas 0.22.0 版本中,使用 pd.get_dummies
来进行独热编码(one-hot encoding)是很常见的做法,特别是在处理数据表(Dataframe)的时候。
import pandas as pd
df_dummies = pd.get_dummies(
df[['convert_me', 'age_col']].apply(lambda x: '_'.join(x.astype(str)), axis=1),
prefix_sep='')
df = pd.concat([df["values"], df_dummies], axis=1)
# Out[39]:
# values Convert1_23 Convert2_33 Convert3_44
# 0 21.71502 1 0 0
# 1 58.35506 0 1 0
# 2 60.41639 0 0 1
12
你可以使用 crosstab
这个函数来实现这个功能:
In [14]: pd.crosstab(index=df['values'], columns=[df['convert_me'], df['age_col']])
Out[14]:
convert_me Convert1 Convert2 Convert3
age_col 23 33 44
values
21.71502 1 0 0
58.35506 0 1 0
60.41639 0 0 1
或者使用 pivot_table
(这里用 len
作为聚合函数,不过你需要手动用零来替换掉 NaN 值):
In [18]: df.pivot_table(index=['values'], columns=['age_col', 'convert_me'], aggfunc=len).fillna(0)
Out[18]:
age_col 23 33 44
convert_me Convert1 Convert2 Convert3
values
21.71502 1 0 0
58.35506 0 1 0
60.41639 0 0 1
关于这个的详细说明可以查看这里: http://pandas.pydata.org/pandas-docs/stable/reshaping.html#pivot-tables-and-cross-tabulations
在 pandas 中,大多数函数会返回一个多层(层级)索引,这里是针对列的。如果你想把这个变成一个单层的,就像在 R 语言中那样,你可以这样做:
In [15]: df_cross = pd.crosstab(index=df['values'], columns=[df['convert_me'], df['age_col']])
In [16]: df_cross.columns = ["{0}_{1}".format(l1, l2) for l1, l2 in df_cross.columns]
In [17]: df_cross
Out[17]:
Convert1_23 Convert2_33 Convert3_44
values
21.71502 1 0 0
58.35506 0 1 0
60.41639 0 0 1