【问题标题】:Filtering a dataframe column for rows that contain certain text为包含特定文本的行过滤数据框列
【发布时间】:2019-05-09 23:46:56
【问题描述】:

我有一个包含某些列的数据框,其中一个是职位,另一个是服务年限。基于这些,我想创建一个新的专栏“生活封面”。我为此创建了这个函数。

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)

这行得通,但我不喜欢有这么大的职位列表,而且列表可能还需要增加,所以也不实用。

我需要包含/排除任何包含 Associate 或 Director 或 Partner 一词的职位。

我已经设法像这样过滤了:

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

返回一个 AttributeError: ("'str' object has no attribute 'str'", 'occured at index 69')

【问题讨论】:

  • 您确定有满足值 7 条件的行吗?
  • 不,这是我想要理解的,但我被困住了——对 Python 也不是很有经验。

标签: python pandas dataframe


【解决方案1】:

str.contains 方法是矢量化字符串操作 (see here)。这意味着它是用于 pandas Series 而不是字符串类型的方法。当您使用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'])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-28
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 2021-04-18
    • 2021-11-11
    相关资源
    最近更新 更多