如何从每个键的数据框字典中获取均值和标准差

How to get mean and std from a dictionary of dataframe per each key

这是我的困境:

我得到了这样一个数据框字典:

dict_df[key]

m1      m2  m3  m4  m5  m6  
10410   5   10  21  33  11
15387   3   10  33  45  13
19026   4   16  27  40  11
26083   5   21  16  29  9
27806   4   17  23  31  7
43820   2   12  27  40  18
49199   7   22  30  38  11
50094   4   9   13  18  4

每个键,它 returns 一个具有相同列名的 DF。

对于每个键,我需要存储一组特征的均值和标准差(让我们以 m2、m3、m4 为例)。

最后,我想获得如下df(数字完全随机):

key   m2_mean    m2_std   m3_mean   m3_std    m4_mean     m4_std
key1    12       55         793      438       44           95
key2    14       442        21       43        14           442
key3    44       1          66       11        42           42
key4    42       42         2        23        98           70

数据集不是很大,所以即使代码很慢也应该没问题。

感谢您的帮助,祝您生活愉快!

首先,让我们定义一些示例数据:

>>> df1 = pd.DataFrame({
        "col1": [1, 2, 3],
        "col2": [4, 5, 6],
    })
>>> df2 = pd.DataFrame({
        "col1": [7, 8, 9],
        "col2": [10, 11, 12],
    })
>>> dict_df = {
        "df1": df1,
        "df2": df2,
    }

现在,您可以使用 .agg() 计算数据帧的均值和标准差(为简单起见,我使用 max),.stack() 将数据帧缩减为一个系列,以及 .to_dict() 以将此结果表示为字符串。请注意,我们将仅使用其中一个数据帧 (df1) 来显示此结果:

>>> df1.agg(["mean", "max"]).stack().to_dict()
{('mean', 'col1'): 2.0, ('mean', 'col2'): 5.0, ('max', 'col1'): 3.0, ('max', 'col2'): 6.0}

有了这个 dict 表示,我们可以使用 pd.DataFrame.from_dict 构建一个数据框,其中包含 dict_df 中每个值的指标:

>>> df = pd.DataFrame.from_dict({
        df_name: df[["col1", "col2"]].agg(["mean", "max"]).stack().to_dict()
        for df_name, df in dict_df.items()
    }, orient="index")
>>> df
    mean        max      
    col1  col2 col1  col2
df1  2.0   5.0  3.0   6.0
df2  8.0  11.0  9.0  12.0

与预期输出的唯一重要区别在于列名,但我们可以手动解决:

>>> df.columns = ["_".join(column) for column in df.columns]
>>> df
     mean_col1  mean_col2  max_col1  max_col2
df1        2.0        5.0       3.0       6.0
df2        8.0       11.0       9.0      12.0

可以为您解决问题的代码:

>>> target_columns = ["m2", "m3", "m4"]
>>> df = pd.DataFrame.from_dict({
        key: df[target_columns].agg(["mean", "std"]).stack().to_dict()
        for key, df in dict_df.items()
    }, orient="index")
>>> df.columns = ["_".join(column) for column in df.columns]
>>> df.index.name = "key"

首先为聚合创建字典,格式为 new_col_name: (dataframe_column_name, aggregare_function):

required_aggs = {f'{col_name}_{agg_name}': (col_name, agg_name)
                 for agg_name in ['mean', 'std']
                 for col_name in df}

上面给出了所需聚合的以下字典和列名。

{
    'm1_mean': ('m1', 'mean'),
    'm1_std': ('m1', 'std'),
    'm2_mean': ('m2', 'mean'),
    'm2_std': ('m2', 'std'),
    'm3_mean': ('m3', 'mean'),
    'm3_std': ('m3', 'std'),
    'm4_mean': ('m4', 'mean'),
    'm4_std': ('m4', 'std'),
    'm5_mean': ('m5', 'mean'),
    'm5_std': ('m5', 'std'),
    'm6_mean': ('m6', 'mean'),
    'm6_std': ('m6', 'std')
}

现在,对于每个数据帧,为键列分配键值,然后按此列分组,并在传递上述聚合字典的解压缩版本的 groupby 对象上调用 .agg

>>> df.assign(key=123).groupby('key').agg(**required_aggs)

       m1_mean  m2_mean  m3_mean  ...    m4_std    m5_std    m6_std
key                               ...                              
123  30228.125     4.25   14.625  ...  6.860862  8.447316  4.140393

PS: 在上面的代码片段中,df 是 dict_df[key] 中的单个数据帧,并且假定此 key 的值是123。您需要对字典中的每个数据帧执行相同的操作。此外,如果您只需要计算特定列的聚合,则只需将 for col_name in df 中的 df 替换为列列表,例如:for col_name in ['m1', 'm2']