假设我有一个包含三个分类列的数据集: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
答案 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