基于多个条件填充新列

时间:2018-07-25 09:47:23

标签: python pandas conditional-statements 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

1 个答案:

答案 0 :(得分:1)

使用:

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

带有检查值的选择列的替代解决方案:

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

详细信息

首先在City列中按set_index,然后检查带有一个或多个空格的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

然后将NaN的匹配值替换为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

最后选择最后一列:

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