`pd.pivot_table`和`pd.DataFrame.groupby` +`pd.DataFrame.unstack`之间是否存在完全重叠?

时间:2016-09-24 09:40:48

标签: python pandas group-by pivot-table

(请注意,有一个问题Pandas: group by and Pivot table difference,但这个问题不同。)

假设您从DataFrame开始

df = pd.DataFrame({'a': ['x'] * 2 + ['y'] * 2, 'b': [0, 1, 0, 1], 'val': range(4)})
>>> df
Out[18]: 
   a  b  val
0  x  0    0
1  x  1    1
2  y  0    2
3  y  1    3

现在假设您要创建索引a,列b,单元格val中的值,并指定如果有两个或更多值的话,该怎么做结果细胞:

b  0  1
a      
x  0  1
y  2  3

然后你可以通过

来做到这一点
df.val.groupby([df.a, df.b]).sum().unstack()

或通过

pd.pivot_table(df, index='a', columns='b', values='val', aggfunc='sum')

所以在我看来,两者之间的对应关系之间有一个简单的对应关系(给定一个,你几乎可以编写一个脚本将其转换为另一个)。我还想到了更复杂的层次索引/列的情况,但我仍然没有看到差异。

有什么我错过的吗?

  • 是否可以使用one而不是其他操作执行操作?

  • 或许,使用其中一种操作更容易执行操作吗?

  • 如果没有,为什么不弃用pivot_talegroupby似乎更为笼统。

1 个答案:

答案 0 :(得分:4)

如果我正确理解了pivot_table(index, columns, values, aggfunc)的源代码,那么它的调整等效于:

df.groupby([index + columns]).agg(aggfunc).unstack(columns)

<强>加

  • 边距(小计和总计为@ayhan has already said
  • pivot_table()还会从列轴移除额外的多级别(请参阅下面的示例)
  • 方便dropna参数:不包括条目全部为NaN
  • 的列

演示:(我从docstring [pivot_table()的源代码]中获取此DF)

In [40]: df
Out[40]:
     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

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

注意顶级栏目:D

In [42]: df.groupby(['A','B','C']).agg([np.sum, np.mean]).unstack('C')
Out[42]:
            D
          sum        mean
C       large small large small
A   B
bar one   4.0   5.0   4.0   5.0
    two   7.0   6.0   7.0   6.0
foo one   4.0   1.0   2.0   1.0
    two   NaN   6.0   NaN   3.0
  

为什么不弃用pivot_tale? groupby似乎更为通用。

IMO,因为它非常易于使用且非常方便! ;)