我在熊猫中发现了一些与标准偏差计算(std)有关的ddof(自由度)参数的异常情况。

对于常规std,无论将其默认值保留为1还是指定为0​​,速度都是相同的。当我将其作为group by的一部分进行操作时,速度要慢10倍左右(我设置的测试DataFrame具有类似的结构到我正在研究的那个)。对于更多的列/行/唯一组,速度下降会更糟。

知道这里发生了什么吗?熊猫需要修复一些错误吗?有没有办法以更快的速度复制ddof=1行为(我经常运行这些std计算)?

import pandas as pd
import datetime
test = pd.DataFrame(np.random.rand(100000,10))

%timeit test.std()
100 loops, best of 3: 18.2 ms per loop
%timeit test.std(ddof=0)
100 loops, best of 3: 18.3 ms per loop

test['group'] = (test[0]*20+1).astype(int)
test['date'] = [datetime.date(2018, 3, g) for g in test['group']]
test = test.set_index(['date','group'])

%timeit test.groupby(level='date').std()
100 loops, best of 3: 6.78 ms per loop
%timeit test.groupby(level='date').std(ddof=0)
10 loops, best of 3: 68.5 ms per loop

最佳答案

这不是一个错误,但它是一个已知问题。

以下是来自pandas的一些groupby.py源代码。


ddof == 1 :(默认值)应用了Cythonized算法。
ddof != 1:应用Python级别的循环。


因此,您将无法使用此方法从pandas中进行优化。

@Substitution(name='groupby')
@Appender(_doc_template)
def var(self, ddof=1, *args, **kwargs):
    """
    Compute variance of groups, excluding missing values

    For multiple groupings, the result index will be a MultiIndex

    Parameters
    ----------
    ddof : integer, default 1
        degrees of freedom
    """
    nv.validate_groupby_func('var', args, kwargs)
    if ddof == 1:
        return self._cython_agg_general('var')
    else:
        self._set_group_selection()
        f = lambda x: x.var(ddof=ddof)
        return self._python_agg_general(f)

09-06 08:37