尝试给出分组(按两个变量)的平均值,如果不可能,请给出 python pandas 中的列平均值

Try and give a grouped (by two variables) average, and if not possible give column average in python pandas

我正在尝试按 2 变量进行分组,并使用分组平均值来填充列中的缺失值。然后,如果这不起作用,我想 groupby 1 变量并给出分组平均值以填充同一列的缺失值,如果那不起作用,我想要给出整列的 平均值 来填充缺失值(没有任何分组,因为这是我最后的手段)。

在数据集中我有很多公司和 5 种不同的产品类型:Laptops/Desktops/Monitors/Tables/MobilePhones

例如,我想尝试对 company_namepl_category 进行分组,并使用 pl_use_energy_demand_(yearly_tec) 列的分组平均值来填充 Apple 平板电脑的缺失值在 pl_use_energy_demand_(yearly_tec) 列中是 nan。但是,如您所见,当我 groupby Apple 和 Tablets_IPAD 时,没有数据可以给出双分组平均值来填充缺失值,所以我想用 Apple 的 nan 值来填充平均值,如果没有整个 Apple 公司的数据,我想用整个列平均值填充 Apple 的 nan。因此,所需的输出将是填写 pl_use_energy_demand_(yearly_tec) 列的 nan 值,使用上面解释的顺序并显示在下面的代码中:

features_to_impute = [
        x for x in dat.columns if dat[x].dtypes != 'O' and dat[x].isnull().mean() > 0.3 and x.startswith('pl')
        ]

def impute_cols(df,var_to_group1,var_to_group2,var_to_impute):
     return df.groupby([var_to_group1,var_to_group2])[var_to_impute].apply(lambda x: np.mean(x))

def impute_cols_2(df,var_to_group_1,var_to_impute):
    return df.groupby([var_to_group_1])[var_to_impute].apply(lambda x: np.mean(x))

for v in dat[features_to_impute]:
    try:
        dat[v+'imp'] = impute_cols(dat,'company_name','pl_category',v) 
    except:
        TypeError
    try:    
       dat[v+'imp'] = impute_cols_2(dat,'company_name',v) 
    except:
         dat[v+'_imp'] = dat[v].fillna(dat[v].mean())

上面的代码即使没有给出错误,它 returns 新的 '_imp' 列充满了 NaN.

关于如何获得我需要的东西有什么建议吗?提前致谢。

我使用

的原因
except:
    TypeError

有时当数据帧被分组时,它没有任何数据来给出分组平均值,所以我的意思是去尝试代码的下一部分。

我猜你快到了。您创建新列的方式不起作用。在你的函数或你的 fo 循环中生成一个列表而不是 pd.Series 应该可以解决问题。

features_to_impute = [
        x for x in dat.columns if dat[x].dtypes != 'O' and dat[x].isnull().mean() > 0.3 and x.startswith('pl')
        ]

def impute_cols(df,var_to_group1,var_to_group2,var_to_impute):
     return df.groupby([var_to_group1,var_to_group2])[var_to_impute].apply(lambda x: np.mean(x))

def impute_cols_2(df,var_to_group_1,var_to_impute):
    return df.groupby([var_to_group_1])[var_to_impute].apply(lambda x: np.mean(x))

for v in dat[features_to_impute]:
    try:
        # create a list() here
        dat[v+'imp'] = list(impute_cols(dat,'company_name','pl_category',v)) 
    except:
        TypeError
    try: 
       # and here   
       dat[v+'imp'] = list(impute_cols_2(dat,'company_name',v)) 
    except:
       dat[v+'_imp'] = dat[v].fillna(dat[v].mean())

试试这个,告诉我它是否有效。 为了将来尝试创建一些可以复制而不是图片的伪数据。这让帮助变得更容易

这不是解决这个问题的最有效方法,但因为时间给我压力,我最终做了这样的事情,它实际上完全符合我的要求:

dict_list_1 = []
for v in dat[features_to_impute]:
    comp_mean = env.groupby('company')[v].mean().to_frame()
    dict_list_1.append(comp_mean)

comp_means = pd.concat(dict_list_1,axis=1,ignore_index=(False))    
comp_means.reset_index(inplace= True) 
   
def unique_id(df,col1,col2):
    return df[col1].astype(str) + "_" + df[col2].astype(str)

dat['company_ptype'] = unique_id(dat,'company_name','pl_category')    
env['company_ptype'] = unique_id(env,'company','category')
   
dict_list_2 = []
for x in dat[features_to_impute]:
    comp_ptype_mean = env.groupby(['company_ptype'])[x].mean().to_frame()
    dict_list_2.append(comp_ptype_mean)

comp_ptype_means = pd.concat(dict_list_2,axis=1,ignore_index=(False))    
comp_ptype_means.reset_index(inplace=True)

dict_list_3 = []
for i in dat[features_to_impute]:
    prod_type_mean = env.groupby(['category'])[i].mean().to_frame()
    dict_list_3.append(prod_type_mean)

prod_type_means = pd.concat(dict_list_3,axis=1,ignore_index=(False))    
prod_type_means.reset_index(inplace=True)

for x in dat[features_to_impute]:
    dat[x] = np.where(dat[x].isnull(),dat['company_ptype'].map(comp_ptype_means.set_index('company_ptype')[x]),dat[x]) # 1st step
    dat[x] = np.where(dat[x].isnull(),dat['pl_category'].map(prod_type_means.set_index('category')[x]),dat[x]) # 2nd step
    dat[x] = dat[x].fillna(dat[x].mean()) # 3rd  step

@Tito,如果您对如何提高效率有任何建议,我很高兴听到并使用它们。

谢谢。