【问题标题】:Can I use crosstab to get a pivot table for summation?我可以使用交叉表来获取数据透视表进行求和吗?
【发布时间】:2017-08-09 23:23:02
【问题描述】:

我使用crosstab 来汇总发布商在给定区域的销售额。 原始数据框如下所示:

Publisher   NA_Sales    EU_Sales    JP_Sales
1   Nintendo    29.08   3.58    6.81
2   Nintendo    15.68   12.76   3.79
3   Nintendo    15.61   10.93   3.28
4   Nintendo    11.27   8.89    10.22
5   Nintendo    23.20   2.26    4.22

我是用数据透视表来做的,现在我想用交叉表来做。

salespivot1=pd.pivot_table(df, index=df.Publisher,
    aggfunc=np.sum).sort_values('NA_Sales', ascending=False)

创建:

          EU_Sales  JP_Sales    NA_Sales
Publisher           
Nintendo    390.05  454.38  775.61
Electronic Arts 373.91  14.35   599.50
Activision  215.90  6.71    432.59
Sony Computer Entertainment 186.56  74.15   266.17
Ubisoft 161.99  7.52    252.74

但使用交叉表我无法重新创建此数据框,因为无论我做什么,它都会将 EU_Sales 堆叠在 NA_Sales 之上

salespivot3=pd.crosstab(index=df.Publisher, columns=['NA_Sales', 'EU_Sales'],
    values=df.NA_Sales, aggfunc=sum)

创建:

col_0   NA_Sales
col_1   EU_Sales
Nintendo    775.61
Electronic Arts  599.50
Activision    432.59
Sony Computer Entertainment  266.17
Ubisoft    252.74

如何使用交叉表重新创建数据框以提供与枢轴相同的结果?

【问题讨论】:

  • 你能发布你想要的数据集/DF吗?
  • 我不明白它与crosstab() 函数有什么关系。你追求的是:df.groupby('Publisher', as_index=False).sum()
  • 好的,我正在学习 gropuby、数据透视表和交叉表是如何工作的。根据我的理解,正确编码后它们应该会产生类似的结果,但是我无法使用交叉表重新创建数据框,使其与使用 groupby 或 pivot_table 相同。你能帮我解决这个问题吗?

标签: python pandas dataframe pivot-table


【解决方案1】:

不可能直接在当前的DF 上使用pd.crosstab(),除非您将它们从宽格式重新调整为长格式,以便生成的标头稍后用作传递给它的函数调用的后续参数。

这里有一个小技巧:

idx = ["Publisher"]
d = pd.melt(df, id_vars=idx)
pd.crosstab(d.Publisher, d.variable, d.value, aggfunc="sum", rownames=idx, colnames=[None])

但老实说,您应该使用专为此目的设计的 groupby/pivot_table 方法。

【讨论】:

  • 谢谢,正是我想要的。我可能永远不会将这种方法用于那种分组,但我想要有形的证据证明它可以以与其他两种类似的方式使用,但现在我理解了一些差异。
【解决方案2】:

我认为您“滥用”pivot_tablecrosstab 方法。

Pivot 方法假设将您的数据集从长格式转换为宽格式。

这是一个小演示:

来源 DF:

In [42]: df
Out[42]:
     A    B      C  D
0  foo  one  small  1
1  foo  one  large  2
2  foo  one  large  2
3  foo  two  small  3
4  foo  two  small  3
5  bar  one  large  4
6  bar  one  small  5
7  bar  two  small  6
8  bar  two  large  7

pivot_table 用法:

In [43]: df.pivot_table(values='D', index=['A', 'B'], columns=['C'], aggfunc='sum')
Out[43]:
C        large  small
A   B
bar one    4.0    5.0
    two    7.0    6.0
foo one    4.0    1.0
    two    NaN    6.0

现在使用pd.crosstab() 方法得到相同的结果:

In [44]: pd.crosstab(index=[df.A,df.B], columns=df.C, values=df.D, aggfunc='sum')
Out[44]:
C        large  small
A   B
bar one    4.0    5.0
    two    7.0    6.0
foo one    4.0    1.0
    two    NaN    6.0

对于您的示例数据集,您只需 groupby + sum

In [46]: df
Out[46]:
  Publisher  NA_Sales  EU_Sales  JP_Sales
1  Nintendo     29.08      3.58      6.81
2  Nintendo     15.68     12.76      3.79
3  Nintendo     15.61     10.93      3.28
4  Nintendo     11.27      8.89     10.22
5  Nintendo     23.20      2.26      4.22

In [47]: df.groupby('Publisher', as_index=False).sum()
Out[47]:
  Publisher  NA_Sales  EU_Sales  JP_Sales
0  Nintendo     94.84     38.42     28.32

更新:如果您想使用crosstab 方法生成相同的数据集,您可以这样做:

In [63]: x = df.set_index('Publisher').stack().reset_index(name='val')

In [64]: x
Out[64]:
   Publisher   level_1    val
0   Nintendo  NA_Sales  29.08
1   Nintendo  EU_Sales   3.58
2   Nintendo  JP_Sales   6.81
3   Nintendo  NA_Sales  15.68
4   Nintendo  EU_Sales  12.76
5   Nintendo  JP_Sales   3.79
6   Nintendo  NA_Sales  15.61
7   Nintendo  EU_Sales  10.93
8   Nintendo  JP_Sales   3.28
9   Nintendo  NA_Sales  11.27
10  Nintendo  EU_Sales   8.89
11  Nintendo  JP_Sales  10.22
12  Nintendo  NA_Sales  23.20
13  Nintendo  EU_Sales   2.26
14  Nintendo  JP_Sales   4.22

In [65]: pd.crosstab(index=x.Publisher, columns=x.level_1, values=x.val, aggfunc='sum')
Out[65]:
level_1    EU_Sales  JP_Sales  NA_Sales
Publisher
Nintendo      38.42     28.32     94.84

注意:我们必须首先将原始 DF 从宽格式转换为长格式,然后使用 pd.crosstab 转换回宽格式

【讨论】:

  • 我理解,但根据这个问题:stackoverflow.com/questions/30679467/… 可以互换使用 3,我实际上能够使用数据透视表和 groupby 来产生正确的结果。但是它没有使用交叉表进行锻炼,所以我不确定代码是否有问题或根本不可能
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多