根据多个条件填充新列
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_index
按 City
列,然后检查 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
s 的匹配值替换为 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
假设我有一个包含三个分类列的数据集: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_index
按 City
列,然后检查 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
s 的匹配值替换为 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