【问题标题】:Create Grand Mean Centered Variables by Group Means in Pandas在 Pandas 中按组均值创建大均值中心变量
【发布时间】:2021-07-08 16:43:00
【问题描述】:

我正在尝试按组创建以均值为中心的大变量。

样本数据为:

import pandas as pd
import numpy as np

dat = {
    'group': ['1', '1', '1', '2', '2', '1', '2'],
    'age': [40, 29, 34, 35, 37, 32, 36],
    'weight': [150, 175, 135, 125, 189, 178, 137],
    'score': [98.0, 77.0, 88.0, 78.0, 78.0, 85.0, 84.0]
    }
df = pd.DataFrame(data=dat)

我正在尝试编写一个函数,该函数将按组估计数据集中所有变量的总均值中心变量。我要尝试的代码如下:

def group_mean_centered(x):
    
    d = []
    
    d.append(x.groupby(x.iloc[:, 0]).transform('mean') - x.iloc[:,0:].mean())
    
    d = np.asarray(d)
    
    d_ = d.reshape(-1,len(x.columns))
        
    dd = pd.DataFrame(d_, columns=[list(x.columns.values)])
    
    return dd

但是,当我这样做时,它会返回一个数据框,其中分组变量 group 也被转换,而不是像括号 [] 中那样获取组

     group           age         weight     score
0   -0.428571 [1]   -0.964286    3.928571    3.0
1   -0.428571 [1]   -0.964286    3.928571    3.0
2   -0.428571 [1]   -0.964286    3.928571    3.0
3    0.571429 [2]    1.285714   -5.238095   -4.0
4    0.571429 [2]    1.285714   -5.238095   -4.0
5   -0.428571 [1]   -0.964286    3.928571    3.0
6    0.571429 [2]    1.285714   -5.238095   -4.0

只是寻找一些关于如何修复代码以保持分组变量 group 不变而不是转换它的想法。

【问题讨论】:

    标签: python-3.x pandas dataframe pandas-groupby aggregate


    【解决方案1】:

    我们可以用groupby + transform 来计算group 的平均值,然后减去mean 的大mean 仅列

    df[['group']].join(df.groupby('group').transform('mean') - df.mean(numeric_only=True))
    

    或者我们可以将数据帧的索引设置为group,然后在level=0 上设置groupbytransform 来计算组均值,然后从梯度中减去这个转换后的组均值意思是得到结果。

    s = df.set_index('group')
    s.groupby(level=0).transform('mean').sub(s.mean()).reset_index()
    

      group       age    weight  score
    0     1 -0.964286  3.928571    3.0
    1     1 -0.964286  3.928571    3.0
    2     1 -0.964286  3.928571    3.0
    3     2  1.285714 -5.238095   -4.0
    4     2  1.285714 -5.238095   -4.0
    5     1 -0.964286  3.928571    3.0
    6     2  1.285714 -5.238095   -4.0
    

    【讨论】:

      【解决方案2】:

      如果您对其他解决方案没问题,您所做的也可以直接由groupby.transform 完成。

      out = ((df.groupby("group").transform("mean")-df.mean())
             .fillna({"group":df['group']}).reindex(columns=df.columns))
      

      print(out)
      
        group       age    weight  score
      0     1 -0.964286  3.928571    3.0
      1     1 -0.964286  3.928571    3.0
      2     1 -0.964286  3.928571    3.0
      3     2  1.285714 -5.238095   -4.0
      4     2  1.285714 -5.238095   -4.0
      5     1 -0.964286  3.928571    3.0
      6     2  1.285714 -5.238095   -4.0
      

      【讨论】:

        【解决方案3】:

        我在您的函数中添加了以下行:dd.iloc[:,0]=x.iloc[:,0]。所以完整的功能是:

        def group_mean_centered(x):
            
            d = []
            
            d.append(x.groupby(x.iloc[:, 0]).transform('mean') - x.iloc[:,0:].mean())
            
            d = np.asarray(d)
            
            d_ = d.reshape(-1,len(x.columns))
                
            dd = pd.DataFrame(d_, columns=[list(x.columns.values)])
            
            dd.iloc[:,0]=x.iloc[:,0]
            
            return dd
        

        这个想法是用原始列替换组列。

        返回:

        group   age weight  score
        0   1   -0.964286   3.928571    3.0
        1   1   -0.964286   3.928571    3.0
        2   1   -0.964286   3.928571    3.0
        3   2   1.285714    -5.238095   -4.0
        4   2   1.285714    -5.238095   -4.0
        5   1   -0.964286   3.928571    3.0
        6   2   1.285714    -5.238095   -4.0
        

        根据需要。

        其他想法:

        我像你一样使用了.iloc 方法,尽管我可能会考虑为你的函数添加一个 groupby 列名的变量,这样你就可以获得更大的灵活性,并且可以利用 pandas 在可读性方面优于 numpy 的优势/便于使用。您始终可以将默认值设置为“组”,这样您就不必在此应用程序中考虑它,但可以在另一个数据帧上使用相同的函数(其中第一列不是分组变量)。

        【讨论】:

          猜你喜欢
          • 2022-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-29
          • 1970-01-01
          • 2017-09-22
          • 1970-01-01
          • 2020-03-12
          相关资源
          最近更新 更多