熊猫:group by和Pivot表差异

use*_*236 46 python pandas

我刚刚开始学习熊猫,并想知道它们pandas groupbypandas pivot_table功能之间是否有任何区别.任何人都可以帮我理解它们之间的区别.帮助将不胜感激.

Dav*_*ust 61

双方pivot_tablegroupby用于收集您的数据帧.差异仅在于结果的形状.

使用pd.pivot_table(df, index=["a"], columns=["b"], values=["c"], aggfunc=np.sum)表创建a在行轴上,b在列轴上,并且值是总和c.

例:

df = pd.DataFrame({"a": [1,2,3,1,2,3], "b":[1,1,1,2,2,2], "c":np.random.rand(6)})
pd.pivot_table(df, index=["a"], columns=["b"], values=["c"], aggfunc=np.sum)

b         1         2
a                    
1  0.528470  0.484766
2  0.187277  0.144326
3  0.866832  0.650100
Run Code Online (Sandbox Code Playgroud)

使用时groupby,给定的尺寸放在列中,并为这些尺寸的每个组合创建行.

在这个例子中,我们创建了一系列的值的总和c,由所有唯一组合进行分组ab.

df.groupby(['a','b'])['c'].sum()

a  b
1  1    0.528470
   2    0.484766
2  1    0.187277
   2    0.144326
3  1    0.866832
   2    0.650100
Name: c, dtype: float64
Run Code Online (Sandbox Code Playgroud)

类似的用法groupby是,如果我们省略['c'].在这种情况下,它会创建一个数据帧(而不是一系列),其中所有剩余列的总和按唯一值和a和分组b.

print df.groupby(["a","b"]).sum()
            c
a b          
1 1  0.528470
  2  0.484766
2 1  0.187277
  2  0.144326
3 1  0.866832
  2  0.650100
Run Code Online (Sandbox Code Playgroud)

  • 谢谢您的回答.我对你发布的内容有疑问.如何`df.groupby(["a","b"])["c"].sum()`与`df.groupby(["a","b"] ["c"]不同)的.sum()` (4认同)
  • 你发布的那一行在语法上是不正确的,但我认为你的意思是`df.groupby(["a","b","c"]).sum()`.这将按a,b和c的唯一组合进行分组,并将剩余列(在上面的示例中不存在)相加. (4认同)
  • 对我来说,这似乎是两种获得相同结果的方法。如果在合计的groupby输出上调用unstack,将会得到pivot_table输出,对吗? (4认同)
  • 如果将“ b”从“列”移动到“索引”,即“ pd.pivot_table(df,index = [“ a”,“ b”],values = [“ c”],aggfunc = np.sum)` ,输出结果与df.groupby([“ a”,“ b”])。sum()相同。 (2认同)

cot*_*ail 21

groupbypivot_table的关系如下(事实上,在底层pivot_table是使用 定义的groupby1

  • 数据透视表=groupby+unstack
  • groupby = 数据透视表 + 堆栈

特别是,如果不使用columns参数,则和两者都会产生相同的结果(如果使用相同的聚合器函数)。pivot_table()groupby()pivot_table()

# sample
df = pd.DataFrame({"a": [1,1,1,2,2,2], "b": [1,1,2,2,3,3], "c": [0,0.5,1,1,2,2]})

# example
gb = df.groupby(['a','b'])[['c']].sum()
pt = df.pivot_table(index=['a','b'], values=['c'], aggfunc='sum')

# equality test
gb.equals(pt)   # True <--- no `columns=` kwarg, no `unstack()`
Run Code Online (Sandbox Code Playgroud)

如果您熟悉 Microsoft Excel,则pivot_table和 的groupby行为类似于 Excel 中的数据透视表功能:

  • groupbybykwarg(即石斑鱼列)对应于 ROWS,聚合的列对应于 VALUES,groupby 方法(mean()sum())对应于您在值字段设置中选择的函数。
  • pivot_tablevalueskwarg 对应于 VALUES、index对应于 ROWS、columns对应于 COLUMNS 以及aggfunc对应于您在值字段设置中选择的函数。

在 pandas 中,就像在 Excel 中一样,groupby会产生长堆叠表,而pivot_table会产生宽表。如果从 中取消长表的堆叠groupby,您会得到与 相同的结果pivot_table


1一般来说,如果我们查看源代码pivot_table()内部会调用__internal_pivot_table(). 此函数从索引和列中创建一个单一的平面列表,并groupby()使用该列表作为石斑鱼进行调用。然后在聚合之后,调用unstack()列列表。

如果列从未被传递,则没有任何内容可以取消堆叠,因此groupbypivot_table产生相同的输出。

这种连接的演示是:

gb = (
    df
    .groupby(['a','b'])[['c']].sum()
    .unstack(['b'])
)
pt = df.pivot_table(index=['a'], columns=['b'], values=['c'], aggfunc='sum')

gb.equals(pt)   # True <--- they produce the same output
Run Code Online (Sandbox Code Playgroud)

正如stack()的逆运算一样unstack(),以下也成立:

pt = df.pivot_table(index=['a'], columns=['b'], values=['c'], aggfunc='sum').stack(['b'])
gb = df.groupby(['a','b'])[['c']].sum()
pt.equals(gb)   # True  <--- they produce the same output
Run Code Online (Sandbox Code Playgroud)

总之,根据用例,一种比另一种更方便,但它们都可以代替另一种使用,并且在正确应用stack()/后unstack(),两者将产生相同的输出。

但是,这两种方法之间存在性能差异。简而言之,pivot_table()比 慢groupby().agg().unstack()。您可以从此答案中了解更多相关信息


小智 11

它更适合使用.pivot_table(),而不是.groupby()当你需要表现出与行和列标签聚集。

.pivot_table()使同时创建行和列标签变得容易并且更可取,即使您可以通过.groupby()很少的额外步骤获得类似的结果。


Myk*_*tko 7

pivot_table是一种二维groupby,您可以按两个变量(列)进行分组,一个变量最终位于索引中,另一个变量位于列中。

通过...分组

在此输入图像描述

数据透视表

数据透视表