在进行数据分析时,时常需要分组计算,使用groupby+apply组合计算。但是当想原地插入新列时,使用groupby + apply 会发生列不匹配的错误。
dat = data[['glass_id','equip_id','unit_id','factory','step_id','label']]
dat = dat.drop_duplicates().reset_index()
dat['step'] = dat['factory']+'_'+dat['step_id']
dat = dat.drop(['step_id','factory','index'],axis=1)
dat['input_equip'] = dat.groupby(by=['step','equip_id']).glass_id.nunique().reset_index().glass_id
dat['input_unit'] = dat.groupby(by=['step','equip_id','unit_id'])['glass_id'].nunique().reset_index().glass_id
dat['unit_ng'] = dat[dat['label']==1].groupby(by=['step','equip_id','unit_id'])['glass_id'].nunique().reset_index().glass_id
dat['ng_all'] = dat[dat.label==1].groupby(by=['step','equip_id'])['glass_id'].nunique().reset_index().glass_id
dat['unit_ok'] = dat['input_unit'] - dat['unit_ng']
dat['ok_all'] = dat['input_equip'] - dat['ng_all']
例如如上代码,返回结果会有很多空值,而且不是空的区域数据也并不对应。
这是因为groupby在计算后行数会仅仅保留groupby的分类行数。
没有办法,只能用中间表+merge的方法添加新列,无形中代码量和内存占有率都高了很多。
dat_input_equip = dat.groupby(by=['step','equip_id'])['glass_id'].nunique().reset_index()
dat_input_unit = dat.groupby(by=['step','equip_id','unit_id'])['glass_id'].nunique().reset_index()
dat_ng_unit = dat[dat['label']==1].groupby(by=['step','equip_id','unit_id'])['glass_id'].nunique().reset_index()
dat_ng_equip = dat[dat.label==1].groupby(by=['step','equip_id'])['glass_id'].nunique().reset_index()
dat = pd.merge(dat,dat_input_equip,on=['step','equip_id'],how='left')
dat = pd.merge(dat,dat_input_unit,on=['step','equip_id','unit_id'],how='left')
dat = pd.merge(dat,dat_ng_unit,on=['step','equip_id','unit_id'],how='left')
dat = pd.merge(dat,dat_ng_equip,on=['step','equip_id'],how='left')
dat.columns = ['glass_id','equip_id','unit_id','label','step','input_equip','input_unit','ng_unit','ng_equip']
dat = dat.fillna(0)
dat['ok_unit'] = dat['input_unit']-dat['ng_unit']
dat['ok_all'] = dat['input_equip']-dat['ng_equip']
dat['ng_all'] = 2
dat['ng_ratio'] = dat['ng_unit']/dat['input_unit']
一直在想有么有什么简单写法,尝试了很多,今天突然发现一个transform函数可以实现,一行代码替代之前的三行,无需中间表,无需merge。
dat['hh'] = dat.groupby(['step','equip_id']).glass_id.transform(lambda x :x.nunique())
特此记录。希望也可以帮到有同样需求的小伙伴