【问题标题】:filling a new column based on multiple criteria根据多个条件填充新列
【发布时间】:2018-07-25 09:47:23
【问题描述】:

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

【问题讨论】:

  • 可以添加小数据样本吗?
  • 感谢您提供数据,预期输出是什么?

标签: python pandas conditional-statements criteria


【解决方案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

详情

首先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

最后选择最后一列:

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.t1 df.t2 dt.3 是对象:df.t1 = ['EU', 'Non EU'], df.t2 = ['US' , 'Non US'] df.t3 = [['Asia', 'Non Asia'],如何使它在这种情况下工作?
  • @FilippoSebastio - 条件是什么?
  • 非常感谢,但我发现这个脚本比 np.where() 还要多。你将如何使用 np.where() 来处理它?看来我做错了
  • @FilippoSebastio - 当然,时刻。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 2023-03-21
  • 2019-05-04
  • 1970-01-01
  • 2020-09-06
  • 2021-06-04
相关资源
最近更新 更多