【发布时间】:2021-11-18 05:15:24
【问题描述】:
我最近在groupby 中遇到了这种奇怪的 Pandas 行为。
我有这个数据框:
>>> df = pd.DataFrame({'a': [1, 2, 3, 1, 2, 3], 'b': [4, 5, 6, 7, 8, 9]})
>>> df
a b
0 1 4
1 2 5
2 3 6
3 1 7
4 2 8
5 3 9
>>>
我想groupby 列a 和sum 列b。
普通groupby 会将列作为索引,但as_index=False 不会:
>>> df.groupby('a')['b'].sum()
a
1 11
2 13
3 15
Name: b, dtype: int64
>>>
但是当我给他们计时:
>>> timeit(lambda: df.groupby('a')['b'].sum(), number=1000)
0.5426476000000093
>>> timeit(lambda: df.groupby('a')['b'].sum(), number=10000)
4.912795499999902
>>> timeit(lambda: df.groupby('a', as_index=False)['b'].sum(), number=1000)
1.419923899999958
>>> timeit(lambda: df.groupby('a', as_index=False)['b'].sum(), number=10000)
11.907147600000144
>>>
您可以看到,由于某种原因,groupby 和 as_index=False 慢了 2.75 倍!
不仅如此!比reset_index还要慢!
>>> timeit(lambda: df.groupby('a', as_index=False)['b'].sum(), number=1000)
1.419923899999958
>>> timeit(lambda: df.groupby('a', as_index=False)['b'].sum(), number=10000)
11.907147600000144
>>> timeit(lambda: df.groupby('a')['b'].sum().reset_index(), number=1000)
1.0641113000001496
>>> timeit(lambda: df.groupby('a')['b'].sum().reset_index(), number=10000)
10.01520289999985
>>>
而reset_index 显然也给出了与as_index=False 相同的输出:
>>> df.groupby('a')['b'].sum().reset_index()
a b
0 1 11
1 2 13
2 3 15
>>>
as_index=False:
>>> df.groupby('a', as_index=False)['b'].sum()
a b
0 1 11
1 2 13
2 3 15
>>>
我可以理解as_index=False 可能会更慢,但不会慢很多...另外,主要是我无法理解为什么reset_index 更快?这是一个额外的功能...
这是为什么? as_index的实现是什么?
我真的很惊讶,我什至认为as_index=False 很有可能比as_index=True 快,因为它不需要将列设置为索引。
但恰恰相反,它实际上是 as_index=True 的 2.75 倍...甚至 reset_index 比 as_index=False 快。
如果是这种情况,为什么as_index=False 不直接使用reset_index?
【问题讨论】:
-
这将是您查看源代码并可能提交 PR 以解决此问题的绝佳机会。开源的力量!
-
@sammywemmy 是的,会调查的!
-
@sammywemmy 老实说,这对我来说是一个有趣的问题:P
标签: python pandas dataframe performance pandas-groupby