【问题标题】:How to get the mean for a whole dataframe instead of columns?如何获得整个数据框而不是列的平均值?
【发布时间】:2018-12-01 19:28:48
【问题描述】:

如何获得 pandas 数据框中所有值(NaN 除外)的平均值?

pd.DataFrame.mean() 仅给出每列(或行,设置axis=1 时)的平均值,但我想要整个事物的平均值。而df.mean().mean() 并不是最明智的选择(见下文)。

请注意,在我的具体真实案例中,数据框具有很大的多索引,这也使事情变得复杂。对于这无关紧要的情况,可以认为@EdChum 的答案更直接,在某些情况下这可能比更快的解决方案更可取。

示例代码

data1 = np.arange(16).reshape(4, 4)
df = pd.DataFrame(data=data1)

df.mean()
0    9.0
1    7.0
2    8.0
3    9.0
dtype: float64

df.mean().mean()
7.5

np.arange(16).mean()
7.5

有效,但如果我屏蔽了 df 的某些部分(实际上,它是数百行/列的相关矩阵,其本身的一半填充了冗余数据),它会变得有趣:

triang = np.triu_indices(4)
data2 = np.arange(4.,20.).reshape(4, 4)
data2[triang]=np.nan
df2 = pd.DataFrame(data=data2)

df2.mean().mean()
15.0

但是(8. + 12. + 13. + 16. + 17. + 18.)/614.

我怎样才能最好地获得“真实”的意思,除了手动编写某种循环来完成上述操作?

【问题讨论】:

    标签: python pandas dataframe mean


    【解决方案1】:

    您可以stack,然后dropna,然后再拨打mean

    In[201]:
    df2.stack().dropna().mean()
    
    Out[201]: 14.0
    

    因此这会将 df 转换为单个列 Series,然后您可以调用 dropna 删除 NaN 行,现在 mean 将正确计算 mean

    【讨论】:

    • 这适用于最小示例,但当 df 具有大(多)索引时,它似乎会失败。可能必须先删除该索引。
    • @JC_CL 好吧,你在你的例子中从来没有说过这个,所以我只能回答所说的
    • 你是对的。当我只对值感兴趣时,我只是没想到指数会起作用。但是,您的方法仍然有效,我只是在堆栈上堆叠......但我会采用np.nanmean(df) 方法,因为它只是62.9 µs per loop,而df.stack().stack().stack().dropna().mean()19.9 ms per loop 上要慢一些。
    • @JC_CL 我忘记了 np.nanmean 这也是我在这里的首选方法,这并不奇怪我的方法较慢,因为生成了很多中间结构。唯一的区别是你把所有东西都放在pandasland
    • 不过,在某些时候可能会派上用场。我在原始问题中添加了注释。
    【解决方案2】:

    你可以使用numpy.nanmean:

    triang = np.triu_indices(4)
    data2 = np.arange(4.,20.).reshape(4, 4)
    data2[triang]=np.nan
    df2 = pd.DataFrame(data=data2)
    
    res = np.nanmean(df2)  # 14.0
    

    也可以通过stack,如@EdChum 所述,但速度较慢:

    df2 = pd.concat([df2]*100000)
    
    %timeit np.nanmean(df2)              # 14.0ms
    %timeit df2.stack().dropna().mean()  # 55.7ms
    

    如果您的数据只是数字,您还可以完全消除 Pandas 开销。

    【讨论】:

    • 我猜当文档说“默认情况下平均值被扁平化数组接管”时,我可能真的只是使用这些值而忽略了我的索引。它确实会产生一个数字,这对于我的真实数据来说也很现实。我会玩一会儿,直到我理解它,然后我才会接受这个答案。
    • @JC_CL, numpy 不会在这里使用索引,它只会使用数据帧值。但请自己测试。
    猜你喜欢
    • 1970-01-01
    • 2012-03-18
    • 2022-08-14
    • 2018-09-26
    • 2021-05-18
    • 2015-09-11
    • 2020-12-27
    • 2017-10-12
    相关资源
    最近更新 更多