pandas groupby没有按列分组转换为索引

Moh*_*OUI 49 python dataframe pandas

pandas groupby的默认行为是将按列转换为索引,并将其从数据框的列列表中删除.例如,假设我有一个包含这些列的dataFrame

col1|col2|col3|col4
Run Code Online (Sandbox Code Playgroud)

如果我通过列col2col3这样的方式应用一个组

df.groupby(['col2','col3']).sum()
Run Code Online (Sandbox Code Playgroud)

数据框df不再包含['col2','col3']列列表.它们会自动转换为结果数据帧的索引.

我的问题是如何在列上执行groupby并将该列保留在数据框中?

use*_*412 75

df.groupby(['col2','col3'], as_index=False).sum()
Run Code Online (Sandbox Code Playgroud)

  • df.groupby(['col2','col3'], as_index=False).sum() 对我不起作用。我在第 2 行有我的旧列(c1、c2、c3、c4)和我的新列(c5、c6)作为标题,但希望 c1-c6 都是标题。 (3认同)
  • 这只是我的问题,还是这在最近的熊猫中不再起作用?使用2.1.0版本测试 (2认同)

Moh*_*OUI 15

添加了以下较为详细的答案,以帮助那些仍然对使用哪种答案感到困惑的人。

\n

首先,针对此问题建议的两种解决方案是:

\n
    \n
  • 解决方案1df.groupby([\'A\', \'B\'], as_index=False).sum()
  • \n
  • 解决方案2df.groupby([\'A\', \'B\']).sum().reset_index()
  • \n
\n

两者都给出了预期的结果。

\n
\n

解决方案一:

\n

正如文档中所解释的,as_index将要求SQL 风格的分组输出,这将有效地要求 pandas 在准备时在输出中保留这些按列分组的输出。

\n
\n

as_index : bool, 默认 True

\n

对于聚合输出,返回以组标签作为索引的对象。\n仅与 DataFrame 输入相关。as_index=False 实际上是\n \xe2\x80\x9cSQL 样式\xe2\x80\x9d分组输出。

\n
\n

例子:

\n

给定以下数据框:

\n
     A     B      C      D\n0    A     1  0.502130  0.959404\n1    A     3  0.335416  0.087215\n2    B     2  0.067308  0.084595\n3    B     4  0.454158  0.723124\n4    B     4  0.323326  0.895858\n5    C     2  0.672375  0.356736\n6    C     5  0.929655  0.371913\n7    D     5  0.212634  0.540736\n8    D     5  0.471418  0.268270\n9    E     1  0.061270  0.739610\n
Run Code Online (Sandbox Code Playgroud)\n

应用第一个解决方案给出:

\n
>>> df.groupby(["A", "B"], as_index=False).sum()\n\n     A     B      C        D\n0    A     1  0.502130  0.959404\n1    A     3  0.335416  0.087215\n2    B     2  0.067308  0.084595\n3    B     4  0.777483  1.618982\n4    C     2  0.672375  0.356736\n5    C     5  0.929655  0.371913\n6    D     5  0.684052  0.809006\n7    E     1  0.061270  0.739610\n
Run Code Online (Sandbox Code Playgroud)\n

正确保留 groupby 列的位置。

\n
\n

解决方案2:

\n

为了理解第二个解决方案,让我们看看上一个命令的输出,as_index = True它是默认行为pandas.DataFrame.groupby(检查文档):

\n
>>> df.groupby(["A", "B"], as_index=True).sum()\n               C       D\nA    B                    \nA    1     0.502130  0.959404\n     3     0.335416  0.087215\nB    2     0.067308  0.084595\n     4     0.777483  1.618982\nC    2     0.672375  0.356736\n     5     0.929655  0.371913\nD    5     0.684052  0.809006\nE    1     0.061270  0.739610\n
Run Code Online (Sandbox Code Playgroud)\n

正如您所看到的,groupby 键成为数据帧的索引。使用pandas.DataFrame.reset_index(检查文档)我们可以将数据帧的索引作为列放回并使用默认索引。这也导致我们得到与上一步相同的结果:

\n
>>> df.groupby([\'A\', \'B\']).sum().reset_index()\n     A     B      C        D\n0    A     1  0.502130  0.959404\n1    A     3  0.335416  0.087215\n2    B     2  0.067308  0.084595\n3    B     4  0.777483  1.618982\n4    C     2  0.672375  0.356736\n5    C     5  0.929655  0.371913\n6    D     5  0.684052  0.809006\n7    E     1  0.061270  0.739610\n
Run Code Online (Sandbox Code Playgroud)\n
\n

基准

\n

请注意,由于第一个解决方案只需 1 步即可满足要求,而第二个解决方案则需要 2 步,因此前者稍快一些:

\n
%timeit df.groupby(["A", "B"], as_index=False).sum()\n3.38 ms \xc2\xb1 21.2 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n\n%timeit df.groupby(["A", "B"]).sum().reset_index()\n3.9 ms \xc2\xb1 365 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n


Bou*_*man 10

另一种方法是:

df.groupby(['col2', 'col3']).sum().reset_index()
Run Code Online (Sandbox Code Playgroud)


set*_*t92 5

不确定,但我认为正确的答案是

df.groupby(['col2','col3']).sum()
df = df.reset_index()
Run Code Online (Sandbox Code Playgroud)

至少是我一直在做的事情,以避免具有多索引的数据帧。

  • 抱歉,我的意思是 Boudewijn Aasman 的回答。该值与“df.groupby(['col2', 'col3']).sum().reset_index()”相同。 (4认同)