【问题标题】:R dcast equivalent in python pandaspython pandas中的R dcast等价物
【发布时间】:2014-09-02 08:05:15
【问题描述】:

我正在尝试在 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 那样轻松地合并它们(组合)?

【问题讨论】:

  • 您想要进行这种特殊转换的更高层次的原因是什么?
  • 我正在创建列,以便在机器学习算法中使用它。
  • 您是否意识到 R 给您的内容有很多列,即1 + length(convert_me) * length(age_col)?起初我以为你会希望每个唯一年龄有一列,但这不是 R 为你做的(你可以看看你是否将相同的年龄分配给两行)。

标签: python r pandas


【解决方案1】:

您可以为此使用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作为聚合函数,但在这里您必须手动将fillna带零的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

【讨论】:

  • 差不多就是这样。有没有办法合并 convert_me 和 age_col?如何在没有级别的情况下创建单个表。
【解决方案2】:

我们可以使用pd.get_dummies函数。在目前的pandas 0.22.0中,one-hot编码到Dataframe时,一般使用pd.get_dummies

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-28
    • 2020-09-14
    • 2018-07-18
    • 2016-06-14
    • 2016-05-23
    • 1970-01-01
    相关资源
    最近更新 更多