首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以使用交叉表得到一个支点表进行求和吗?

我可以使用交叉表得到一个支点表进行求和吗?
EN

Stack Overflow用户
提问于 2017-03-18 11:34:15
回答 2查看 8.2K关注 0票数 2

我使用crosstab来总结出版商在特定领域的销售情况。原始的dataframe如下所示:

代码语言:javascript
复制
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

我用枢轴表做了,现在我想用交叉表来做。

代码语言:javascript
复制
salespivot1=pd.pivot_table(df, index=df.Publisher,
    aggfunc=np.sum).sort_values('NA_Sales', ascending=False)

创建:

代码语言:javascript
复制
          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上。

代码语言:javascript
复制
salespivot3=pd.crosstab(index=df.Publisher, columns=['NA_Sales', 'EU_Sales'],
    values=df.NA_Sales, aggfunc=sum)

创建:

代码语言:javascript
复制
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

如何使用交叉表重新创建数据帧,以获得与支点相同的结果?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-18 12:17:40

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

这里有一个轻微的黑客攻击:

代码语言:javascript
复制
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方法,该方法正是为此目的而设计的。

票数 7
EN

Stack Overflow用户

发布于 2017-03-18 12:07:56

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

Pivot方法应该将数据集从长格式转换为宽格式。

下面是一个小演示:

来源DF:

代码语言:javascript
复制
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使用:

代码语言:javascript
复制
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()方法得到相同的结果:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

UPDATE:如果您无论如何都希望使用crosstab方法生成相同的数据集,您可以这样做:

代码语言:javascript
复制
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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42873838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档