熊猫 groupby 没有将按列分组转换为索引
Posted
技术标签:
【中文标题】熊猫 groupby 没有将按列分组转换为索引【英文标题】:pandas groupby without turning grouped by column into index 【发布时间】:2015-11-10 14:55:33 【问题描述】:pandas groupby 的默认行为是将 group by 列转换为索引,并将它们从数据框的列列表中删除。例如,假设我有一个包含这些列的数据框
col1|col2|col3|col4
如果我以这种方式应用 groupby 列 col2
和 col3
df.groupby(['col2','col3']).sum()
数据框df
的列列表中不再有['col2','col3']
。它们会自动变成结果数据帧的索引。
我的问题是如何对列执行 groupby 并将该列保留在数据框中?
【问题讨论】:
【参考方案1】:df.groupby(['col2','col3'], as_index=False).sum()
【讨论】:
df.groupby(['col2','col3'], as_index=False).sum() 对我不起作用。我在第 2 行有我的旧列(c1、c2、c3、c4)和我的新列(c5、c6)作为标题,但希望 c1-c6 都是标题。 它会从新生成的 df 中删除“col2”和“col3”,所以这不是问题的答案,而是“Boudewijn Aasman 的答案是?”【参考方案2】:另一种方法是:
df.groupby(['col2', 'col3']).sum().reset_index()
【讨论】:
【参考方案3】:不确定,但我认为正确的答案是
df.groupby(['col2','col3']).sum()
df = df.reset_index()
至少我一直在做的是避免使用多索引的数据帧。
【讨论】:
这与半年前发布的上述解决方案完全相同。只是没有链接。 是与否,也与问题相似,与接受答案的区别在于 as_index=False 与 .reset_index(),通常相同但并非总是 ***.com/a/51933722/1598953。虽然我不记得为什么我的旧自我发布它,但我认为接受的答案对他不起作用。 对不起,我的意思是 Boudewijn Aasman 的回答。那个是相同的df.groupby(['col2', 'col3']).sum().reset_index()
。【参考方案4】:
添加了以下有点详细的答案,以帮助那些仍然对使用哪种答案变体感到困惑的人。
首先,针对这个问题,建议的两种解决方案是:
解决方案 1:df.groupby(['col2', 'col3'], as_index=False).sum()
解决方案 2:df.groupby(['col2', 'col3']).sum().reset_index()
两者都给出了预期的结果。
解决方案一:
如文档中所述,as_index
将要求 SQL 样式 分组输出,这将有效地要求 pandas 在输出中保留这些按列分组的内容准备好了。
as_index:布尔型,默认为真
对于聚合输出,返回以组标签为索引的对象。 仅与 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
基准测试
请注意,由于第一个解决方案在 1 步中实现了要求,而在第二个解决方案中是 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)
【讨论】:
使用 as_index=False 创建的数据框(此处为解决方案 1)不包含为分组指定的列(col1 和 col2 在您的示例中)。因此解决方案 1 本身不是一个有效的答案。以上是关于熊猫 groupby 没有将按列分组转换为索引的主要内容,如果未能解决你的问题,请参考以下文章