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

时间:2015-08-17 20:46:16

标签: python pandas dataframe

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

col1|col2|col3|col4

如果我通过这种方式使用列col2col3来应用群组

df.groupby(['col2','col3']).sum()

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

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

4 个答案:

答案 0 :(得分:57)

df.groupby(['col2','col3'], as_index=False).sum()

答案 1 :(得分:7)

另一种方法是:

df.groupby(['col2', 'col3']).sum().reset_index()

答案 2 :(得分:2)

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

df.groupby(['col2','col3']).sum()
df = df.reset_index()

至少我一直在努力避免使用具有多索引的数据帧。

答案 3 :(得分:0)

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

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

  • 解决方案1 ​​df.groupby(['col2', 'col3'], as_index=False).sum()
  • 解决方案2 df.groupby(['col2', 'col3']).sum().reset_index()

都给出了预期的结果。


解决方案1:

如文档中所述,as_index将要求 SQL样式 分组输出,这将有效地要求熊猫在输出中按列将其保留准备好了。

as_index :布尔值,默认为True

对于聚合输出,返回带有组标签的对象作为索引。 仅与DataFrame输入有关。 as_index = False有效 “ SQL风格” 分组的输出。

示例:

给出以下数据框:

  col1  col2      col3      col4
0    A     1  0.502130  0.959404
1    A     3  0.335416  0.087215
2    B     2  0.067308  0.084595
3    B     4  0.454158  0.723124
4    B     4  0.323326  0.895858
5    C     2  0.672375  0.356736
6    C     5  0.929655  0.371913
7    D     5  0.212634  0.540736
8    D     5  0.471418  0.268270
9    E     1  0.061270  0.739610

应用第一个解决方案将得出:

>>> df.groupby(["col1", "col2"], as_index=False).sum()

  col1  col2      col3      col4
0    A     1  0.502130  0.959404
1    A     3  0.335416  0.087215
2    B     2  0.067308  0.084595
3    B     4  0.777483  1.618982
4    C     2  0.672375  0.356736
5    C     5  0.929655  0.371913
6    D     5  0.684052  0.809006
7    E     1  0.061270  0.739610

正确保存了groupby列的位置。


解决方案2:

要了解第二种解决方案,让我们看一下带有as_index = True的前一个命令的输出,它是pandas.DataFrame.groupby的默认行为(选中documentation):

>>> df.groupby(["col1", "col2"], as_index=True).sum()
               col3      col4
col1 col2                    
A    1     0.502130  0.959404
     3     0.335416  0.087215
B    2     0.067308  0.084595
     4     0.777483  1.618982
C    2     0.672375  0.356736
     5     0.929655  0.371913
D    5     0.684052  0.809006
E    1     0.061270  0.739610

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

>>> df.groupby(['col1', 'col2']).sum().reset_index()
  col1  col2      col3      col4
0    A     1  0.502130  0.959404
1    A     3  0.335416  0.087215
2    B     2  0.067308  0.084595
3    B     4  0.777483  1.618982
4    C     2  0.672375  0.356736
5    C     5  0.929655  0.371913
6    D     5  0.684052  0.809006
7    E     1  0.061270  0.739610

基准

请注意,由于第一种解决方案一步一步达到要求,而第二种解决方案则需要2步,因此前者要快一些:

%timeit df.groupby(["col1", "col2"], as_index=False).sum()
3.38 ms ± 21.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df.groupby(["col1", "col2"]).sum().reset_index()
3.9 ms ± 365 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)