熊猫-用同一列中的其他值替换列中的值

时间:2019-05-09 18:42:52

标签: python pandas

数据框,其中包含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,但是没有运气。

4 个答案:

答案 0 :(得分:2)

我将在ffill内使用bffilgroupby

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 undefinedundefined。然后,更新df的确切切片。

步骤
m创建为一系列CLASS时,会将CATEGORY作为undifined,并将其值设为唯一的not undefined。使用isin选择合格的行,然后使用whereundefined转换为NaN。最后,在这些行上GroupbyCLASS,每组ffillbfill填充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'