【问题标题】:Keep substrings if substrings are in a list如果子字符串在列表中,则保留子字符串
【发布时间】:2021-06-25 07:05:58
【问题描述】:
我有一个包含字符串的列和一个包含我希望保留在列中的字符串的列表。如果列表中不存在子字符串,请将其删除。请注意,列中字符串的开头或结尾不能有双空格或空格。
我怎样才能有效地做到这一点?
df['column']
>>>
0 good day happy night
1 good bird sad day
2 day over ready
ls = ['good', 'day']
输出:
df['column']
>>>
0 good day
1 good day
2 day
【问题讨论】:
标签:
python
pandas
string
list
【解决方案1】:
将Series.str.findall 与| 加入| 用于正则表达式OR 与Series.str.join 用于连接列表:
ls = ['good', 'day']
df['column'] = df['column'].str.findall('|'.join(ls)).str.join(' ')
print (df)
column
0 good day
1 good day
2 day
如果需要按单词边界在空格之间匹配值:
#daytime changed
print (df)
column
0 good daytime happy night
1 good bird sad day
2 day over ready
ls = ['good', 'day']
pat = '|'.join(r"\b{}\b".format(x) for x in ls)
df['column1'] = df['column'].str.findall(pat).str.join(' ')
df['column2'] = df['column'].str.findall('|'.join(ls)).str.join(' ')
print (df)
column column1 column2
0 good daytime happy night good good day
1 good bird sad day good day good day
2 day over ready day day
另一个想法是使用 lambda 函数和查找列表转换为集合:
sets = set(ls)
df['column1'] = df['column'].apply(lambda x: ' '.join(y for y in x.split() if y in sets))
【解决方案2】:
使用apply 和一个 lambda 函数:
df['column'].apply(lambda row: ' '.join(list(set(row.split()) & ls)))
请注意,使用集合可能会更改字符串的顺序。
MCVE:
df = pd.DataFrame({'column':['good day happy night', 'good bird sad day', 'day over ready']})
# column
# 0 good day happy night
# 1 good bird sad day
# 2 day over ready
ls = ['good', 'day']
ls = set(ls)
df['column'].apply(lambda row: ' '.join(list(set(row.split()) & ls)))
# 0 good day
# 1 good day
# 2 day
# Name: column, dtype: object