pandas groupby的默认行为是将按列转换为索引,并将其从数据框的列列表中删除。例如,假设我有一个包含这些列的dataFrame
col1|col2|col3|col4
如果我通过这种方式使用列col2
和col3
来应用群组
df.groupby(['col2','col3']).sum()
数据框df
在列表列中不再包含['col2','col3']
。它们会自动转换为结果数据帧的索引。
我的问题是如何在列上执行groupby并将该列保留在数据框中?
答案 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)
添加了以下稍微详细的答案,以帮助那些仍对使用哪种答案感到困惑的人。
首先,针对此问题建议的两种解决方案是:
df.groupby(['col2', 'col3'], as_index=False).sum()
df.groupby(['col2', 'col3']).sum().reset_index()
都给出了预期的结果。
如文档中所述,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列的位置。
要了解第二种解决方案,让我们看一下带有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)