数据框,其中包含3列:
FLAG CLASS CATEGORY
yes 'Sci' 'Alpha'
yes 'Sci' 'undefined'
yes 'math' 'Beta'
yes 'math' 'undefined'
yes 'eng' 'Gamma'
yes 'math' 'Beta'
yes 'eng' 'Gamma'
yes 'eng' 'Omega'
yes 'eng' 'Omega'
yes 'eng' 'undefined'
yes 'Geog' 'Lambda'
yes 'Art' 'undefined'
yes 'Art' 'undefined'
yes 'Art' 'undefined'
我想用该类具有的其他类别值(如果有的话)填充CATEGORY列中的“ undefined”值。例如。科学类将使用“ Alpha”填充其空白类别,“数学”类将使用“ Beta”填充其“未定义”类别。
如果要考虑2个或更多类别,请保持原样。 例如。英语课“ eng”有两个类别“ Gamma”和“ Omega”,因此英语课的“ undefined”类别将保留为“ undefined”
如果某类的所有类别均为“未定义”,则保留为“未定义”。
结果
FLAG CLASS CATEGORY
yes 'Sci' 'Alpha'
yes 'Sci' 'Alpha'
yes 'math' 'Beta'
yes 'math' 'Beta'
yes 'eng' 'Gamma'
yes 'math' 'Beta'
yes 'eng' 'Gamma'
yes 'eng' 'Gamma'
yes 'eng' 'Omega'
yes 'eng' 'Omega'
yes 'eng' 'undefined'
yes 'Geog' 'Lambda'
yes 'Art' 'undefined'
yes 'Art' 'undefined'
yes 'Art' 'undefined'
需要通用化。我在“班级”列中有很多班级,无法负担对“ Sci”或“ eng”的编码。
我一直在尝试使用多个np.wheres,但是没有运气。
答案 0 :(得分:2)
我将在ffill
内使用bffil
和groupby
s=df.CATEGORY.mask(df.CATEGORY.eq('undefined'))
s2=s.groupby(df['CLASS']).transform('nunique')
df.loc[s2.eq(1)&s.isnull(),'CATEGORY']=s.groupby(df.CLASS).apply(lambda x : x.ffill().bfill())
df
Out[388]:
FLAG CLASS CATEGORY
0 yes Sci Alpha
1 yes Sci Alpha
2 yes math Beta
3 yes math Beta
4 yes eng Gamma
5 yes math Beta
6 yes eng Gamma
7 yes eng Omega
8 yes eng Omega
9 yes eng undefined
10 yes Geog Lambda
11 yes Art undefined
12 yes Art undefined
13 yes Art undefined
答案 1 :(得分:1)
尝试以下方法:
df['CATEGORY'] = df.replace('undefined', np.nan, regex=True).groupby('CLASS')['CATEGORY'].apply(lambda x: x.fillna(x.mode()[0]) if not x.isna().all() else x).replace(np.nan, "\'undefined\'")
答案 2 :(得分:1)
修改:
我使用isin
添加了另一个解决方案,以过滤出有效的class
来更新not undefined
和undefined
。然后,更新df
的确切切片。
步骤:
将m
创建为一系列CLASS
时,会将CATEGORY
作为undifined
,并将其值设为唯一的not undefined
。使用isin
选择合格的行,然后使用where
将undefined
转换为NaN
。最后,在这些行上Groupby
乘CLASS
,每组ffill
,bfill
填充NaN
并分配回df
m = df.query('CATEGORY!="undefined"').drop_duplicates().CLASS.drop_duplicates(keep=False)
df[df.CLASS.isin(m)] = df[df.CLASS.isin(m)].where(df!='undefined').groupby('CLASS').ffill().bfill()
此解决方案看起来更干净,但我不知道它是否比使用groupby
的速度慢
原始:
我的解决方案从由唯一的'not undefined'
值映射的'undefined'
构造了'not undefined'
:
m = df.query('CATEGORY != "undefined"').drop_duplicates().CLASS.drop_duplicates(keep=False)
t = df.query('CATEGORY == "undefined"').CLASS.map(df.loc[m.index].set_index('CLASS').CATEGORY)
df['CATEGORY'].update(t)
Out[553]:
FLAG CLASS CATEGORY
0 yes Sci Alpha
1 yes Sci Alpha
2 yes math Beta
3 yes math Beta
4 yes eng Gamma
5 yes math Beta
6 yes eng Gamma
7 yes eng Omega
8 yes eng Omega
9 yes eng undefined
10 yes Geog Lambda
11 yes Art undefined
12 yes Art undefined
13 yes Art undefined
答案 3 :(得分:0)
您可以使用布尔型indesing
df[(df['CLASS']=='Sci'& df['CATEGORY']=='undefined','CATEGORY')]='Alpha'
df[(df['CLASS']=='math'& df['CATEGORY']=='undefined','CATEGORY')]='Beta'