【问题标题】:Averaging blocks of cells in a pandas dataframe对 pandas 数据框中的单元格块进行平均
【发布时间】:2017-04-22 01:34:08
【问题描述】:

由于难以解释的原因,我想对一个稀疏地填充随机值的 pandas 数据帧中的单元块块进行平均。数据框将始终具有 sqrt(列数 x 索引数)值——其余的都是 NaN。这些值大致均匀分布,因此如果我平均大小合适的单元格块,我希望每个块中有一个值。

这是我的例子。对于 100 列和 100 个索引,我有 100 个值随机分布在整个数据框中。我希望每个 10x10 块有 ~1 个值,所有其他值都是 NaN。如何将每个 10x10 块变成一个单元格(平均其中的 10 列、10 个索引和值?

我的代码:

import pandas as pd
import numpy as np
import math

number_of_planes = 100

thicknesses = np.empty(number_of_planes)
cos_thetas = np.empty(number_of_planes)
phis = np.empty(number_of_planes)
for i in range(0,number_of_planes):
    r = 1
    phi = np.random.uniform(0,2*math.pi)
    theta = math.acos(2*np.random.uniform(0.5,1) - 1)
    thickness = np.random.uniform(0,0.4)

    phis[i] = phi
    cos_thetas[i] = math.cos(theta)
    thicknesses[i] = thickness

thick_df = pd.DataFrame(columns=phis, index=cos_thetas)

for i in range(0, len(thicknesses)):
    thick_df.set_value(cos_thetas[i], phis[i], thicknesses[i], takeable=False)

thick_df = thick_df.sort_index(axis=0, ascending=False)
thick_df = thick_df.sort_index(axis=1)

【问题讨论】:

    标签: python pandas numpy dataframe average


    【解决方案1】:

    IIUC 您可以将每个轴重塑为一个 4D 数组,将每个轴分成两个长度为 sqrt(len of each axis) 的轴,并计算沿第二个和第四个轴的平均值,忽略 NaNsnp.nanmean -

    arr = thick_df.values.astype(float)
    n = int(np.sqrt(number_of_planes))
    
    out = np.nanmean(arr.reshape(n,n,n,n),axis=(1,3))
    
    indx = thick_df.index.values.reshape(-1,n).mean(1)
    coln = thick_df.columns.values.reshape(-1,n).mean(1)
    df_out = pd.DataFrame(out, index=indx, columns= coln)
    

    示例运行 -

    In [174]: thick_df # number_of_planes = 4
    Out[174]: 
              4.550477  5.138694  5.411510 6.123163
    0.981987       NaN       NaN  0.393233      NaN
    0.565861  0.186647       NaN       NaN      NaN
    0.193190       NaN       NaN       NaN  0.11626
    0.088382       NaN  0.166189       NaN      NaN
    
    In [175]: df_out
    Out[175]: 
              4.844586  5.767337
    0.773924  0.186647  0.393233
    0.140786  0.166189  0.116260
    

    【讨论】:

    • 好的,我想我明白了,但是当我尝试将它应用到我的代码时它不起作用。我需要更改哪一部分才能使其适用于我的 100x100 数据帧?
    • @Rebecca 你能详细说明没用的部分吗? NaNs 在里面还是值不匹配?应该可以在没有任何更改的情况下工作。
    • 我收到运行时警告说“空切片的平均值”,结果数据框看起来没有变化。
    • @Rebecca 要创建输出数据框,您需要使用pd.Dataframe(out),其中out = np.nanmean(thick_df.values.astype(float).reshape(n,n,n,n),axis=(1,3))。在警告问题上,因为有块具有所有NaNs,所以它不能忽略,这就是为什么这些块的警告和输出将是NaN
    • 糟糕,我的错。完美运行!仍然有一些 NaN 只是因为它没有真正均匀地填充,但您的解决方案肯定有效。非常感谢!
    【解决方案2】:
    m, n = 10, 10
    row_groups = np.arange(len(thick_df.index)) // m
    col_groups = np.arange(len(thick_df.columns)) // n
    
    grpd = pd.DataFrame(thick_df.values, row_groups, col_groups)
    
    val = pd.to_numeric(grpd.stack(), 'coerce').groupby(level=[0, 1]).mean().unstack().values
    idx = thick_df.index.to_series().groupby(row_groups).mean().values
    col = thick_df.columns.to_series().groupby(col_groups).mean().values
    
    pd.DataFrame(val, idx, col)
    

    【讨论】:

    • 与上述解决方案相同的问题——我需要列和索引标签是它们之前值的平均值!
    猜你喜欢
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 2017-03-01
    • 1970-01-01
    • 2020-05-17
    相关资源
    最近更新 更多