根据多个条件填充新列

filling a new column based on multiple criteria

假设我有一个包含三个分类列的数据集:df.type1 df.type2 df.type3 我想创建一个新列 [df.new] 它需要:

df.new = df.type1 if df.type1 is true and the remaining are false
df.new = df.type2 if df.type2 is true and the remaining are false
df.new = df.type3 if df.type3 is true and the remaining are false

最好的方法是什么?我对 np.where() 感到很困惑 - 太长而且脚本太密集

示例:

City    dt.t1   dt.t2   dt.t3
NY       US Non    EU   Non Asia
Rome     Non US    EU   Non Asia
SF       US Non    EU   Non Asia
HK       Non US    Non EU   Asia

我的最终结果是:

City  dt.new
NY    US
Rome  EU
SF    US
HK    Asia

使用:

df = df.set_index('City')
df['dt.new'] = df.mask(df.apply(lambda x: x.str.contains('Non\s+'))).ffill(axis=1).iloc[:, -1]

具有 select 个检查值列的替代解决方案:

cols = df.filter(regex='^dt\.').columns
#or use list of columns names
#cols = ['dt.t1','dt.t2','dt.t3']
df['dt.new'] = df[cols].mask(df[cols].apply(lambda x: x.str.contains('Non\s+'))).ffill(axis=1).iloc[:, -1]

print (df)
       dt.t1   dt.t2     dt.t3 dt.new
City                                 
NY        US  Non EU  Non Asia     US
Rome  Non US      EU  Non Asia     EU
SF        US  Non EU  Non Asia     US
HK    Non US  Non EU      Asia   Asia

详情:

首先 set_indexCity 列,然后检查 Non 包含一个或多个空格的字符串:

df = df.set_index('City')

print (df.apply(lambda x: x.str.contains('Non\s+')))
      dt.t1  dt.t2  dt.t3
City                     
NY    False   True   True
Rome   True  False   True
SF    False   True   True
HK     True   True  False

然后将 NaNs 的匹配值替换为 mask:

print (df.mask(df.apply(lambda x: x.str.contains('Non\s+'))))
     dt.t1 dt.t2 dt.t3
City                  
NY      US   NaN   NaN
Rome   NaN    EU   NaN
SF      US   NaN   NaN
HK     NaN   NaN  Asia

每行正向填充非缺失值:

print (df.mask(df.apply(lambda x: x.str.contains('Non\s+'))).ffill(axis=1))
     dt.t1 dt.t2 dt.t3
City                  
NY      US    US    US
Rome   NaN    EU    EU
SF      US    US    US
HK     NaN   NaN  Asia

最后 select 最后一列:

print (df.mask(df.apply(lambda x: x.str.contains('Non\s+'))).ffill(axis=1).iloc[:, -1])
City
NY        US
Rome      EU
SF        US
HK      Asia
Name: dt.t3, dtype: object

编辑:

m1 = df['dt.t1'] == 'US'
m2 = df['dt.t2'] == 'EU'
m3 = df['dt.t3'] == 'Asia'

df['dt.new'] = np.select([m1, m2, m3], ['US','EU','Asia'], default=None)

或者:

df['dt.new'] = np.where(m1, 'US',
               np.where(m2, 'EU',
               np.where(m3, 'Asia', None)))

print (df)
   City   dt.t1   dt.t2     dt.t3 dt.new
0    NY      US  Non EU  Non Asia     US
1  Rome  Non US      EU  Non Asia     EU
2    SF      US  Non EU  Non Asia     US
3    HK  Non US  Non EU      Asia   Asia