自定义均值实施比 pandas 默认均值慢。如何优化?

Custom mean implementation is slower than pandas default mean. How to optimize?

我想求 pandas Dataframe 的平均值。所以我使用了 pandas 默认提供的以下均值函数。 Link to its doc

df.mean()

但是这个函数的问题是,如果所有值的总和大于数据类型的限制,就会发生溢出。就我而言,我有 float16 的数据并且记录数超过 2000 万条。所以显然所有记录的总和将溢出 float16。一种方法是将数据类型更改为 float64,但这将使用过多的额外内存,因为每个值都在 ~1900-2100 范围内。所以我想使用给定的方法 here 迭代地实现均值。这是我对 pandas 数据框

的实现
def mean_without_overflow(df):
    avgs = []
    for column in df:
        avg, t = 0, 1
        for data in df[column]:
            if not math.isnan(data):
                avg += (data-avg) / t;
                t += 1
        avgs.append(avg)
    return avgs

在这里,对于每一列,我都在迭代所有行。因此总迭代次数为 # of columns * # of records。然而,这不会溢出并给出整个数据帧的正确平均值,但它比 pandas 提供的默认均值函数慢得多。

那么我在这里缺少什么?我该如何优化呢?或者 pandas 中是否有任何开箱即用的函数可用于迭代查找均值?

编辑: 溢出似乎是计算均值时的常见问题。我想知道为什么 pandas 中的默认 mean() 没有使用这种迭代方法来实现,这种方法可以防止较小范围的数据类型溢出。

在 pandas 中循环很慢,这就是为什么您可以使用 apply 代替。

def mean_without_overflow(column):
    avg, t = 0, 1
    for data in column:
        if not math.isnan(data): 
            avg += (data-avg) / t
            t += 1 
    return avg

然后我们可以计算 df 的整个均值。

mean_df = np.mean(df.apply(mean_without_overflow))

以上脚本与

相同
mean_df = np.mean(df.apply(np.mean))

如果我错了请纠正我,但我相信:

sum(l) / len(l) = sum(l[:n]) / len(l) + sum(l[n:2*n]) / len(l) + ...

这意味着您可以 np.sum 批量 n 这样 n * 2100 < max_float16

我自己找到了解决方案。逻辑是首先通过将所有值除以系列长度(记录数)来归一化所有值,然后使用默认值 df.mean() 然后将归一化平均值乘以记录数:这是从 1 分钟 37 秒到3.13 秒。但我仍然不明白为什么 pandas 实现没有使用这种优化。

def mean_without_overflow_fast(col):
    col /= len(col)
    return col.mean() * len(col)

按如下方式使用此功能:

print (df.apply(mean_without_overflow_fast))