对包含某些文本的行过滤数据框列



我有一个包含某些列的数据框架,其中之一是位置,另一个是服务年。基于这些,我想创建一个新的专栏" Life Cover"。我为此创建了此功能。

def LifeCover(row):
if row['Years of Service']>5:
    val = 8
elif row['Years of Service']>2 and row['Position'] in ['Associate', 'Director', 'Director of Facilities Management', 'Director of Promise', 'Director, Head of Facilities Management']:
    val = 8
elif row['Years of Service']>2 and row['Position'] not in ['Associate', 'Director', 'Director of Facilities Management', 'Director of Promise', 'Director, Head of Facilities Management']:
    val = 7
else:
    val = 3
return val
df['Potential Life Cover Level'] = df.apply(LifeCover, axis=1)

这有效,但我不喜欢拥有如此大的职位清单,事实证明,列表也可能需要增长,因此也不实用。

我需要的是包括/排除任何包含副词或董事或合作伙伴的职位。

我已经设法过滤了:

target = ['Associate', 'Director', 'Partner']
dfhigh = df[df['Position'].apply(lambda sentence: any(word in sentence for word in target))]
dflow = df[~df['Position'].apply(lambda sentence: any(word in sentence for word in target))]

因此,我得到了一个具有高位置的数据框,一个具有低位置。

,然后我尝试将其包括在我的功能中:

def LifeCover2(row):
if row['Years of Service']>5:
    val = 8
elif row['Years of Service']>2 and row['Position'] in dfhigh['Position']:
    val = 8
elif row['Years of Service']>2 and row['Position'] in dflow['Position']:
    val = 7
else:
    val = 3
return val

但是出于某种原因,它仅返回值8或3。

我也尝试过:

def LifeCover2(row):
if row['Years of Service']>5:
    val = 8
elif row['Years of Service']>2 and row['Position'].str.contains('Associate|Director|Partner'):
    val = 8
elif row['Years of Service']>2 and (~row['Position'].str.contains('Associate|Director|Partner')):
    val = 7
else:
    val = 3
return val

返回一个属性:("'str'对象没有属性'str'",'发生在索引69'(

str.contains方法是矢量化的字符串操作(请参见此处(。这意味着它是PANDAS系列而不是字符串类型的方法。当您使用df.apply时,PANDAS试图为您选择的列的每个元素使用str.contains而不是在系列级别进行。

我建议采用以下方法:

df['LifeCover2'] = 3
df['LifeCover2'] = np.where(df['Years of Service']>5, 8, df['LifeCover2'])
df['LifeCover2'] = np.where((df['Years of Service']>2) & 
                        (df['Position'].str.contains('Associate|Director|Partner')), 8, df['LifeCover2'])
df['LifeCover2'] = np.where((df['Years of Service']>2) & 
                        (~df['Position'].str.contains('Associate|Director|Partner')), 7, df['LifeCover2'])

最新更新