【发布时间】:2019-10-16 22:31:54
【问题描述】:
我有一个包含术语和句子的平面文件。如果在句子中找到任何术语,我需要附加 |present (term|present)。基本上,模式匹配(不区分大小写)和追加 |present。此外,我们需要保留与句子中相同的大小写。哪种方法在 Python 中可行且更快。我尝试使用 Oracle 正则表达式,处理 70k 条记录需要几天时间。
现在我正在使用下面的代码。有没有更好的方法。而且使用当前方法,它适用于 50 条记录,但 df['words'] 在运行整个 70k 记录时为空。不知道是什么原因。
from pandas import DataFrame
df = {'term': ['Ford', 'EXpensive', 'TOYOTA', 'Mercedes Benz', 'electric', 'cars'],
'sentence': ['Ford is less expensive than Mercedes Benz.' ,'toyota, hyundai mileage is good compared to ford','tesla is an electric-car','toyota too has electric cars','CARS','CArs are expensive.']
}
from pandas import DataFrame
import re
df = DataFrame(df,columns= ['term','sentence'])
pattern = "|".join(f"\w*(?<![A-Za-z-;:,/|]){i}\\b" for i in df["term"])
df["words"]= df['sentence'].str.findall(pattern, flags=re.IGNORECASE)
def replace_values(row):
if len(row.words)>0:
pat = r"(\b"+"|".join(row.words) +r")(\b)"
row.sentence = re.sub(pat, "\\1|present\\2", row.sentence)
return row
df = df.apply(replace_values, axis=1)
【问题讨论】:
-
你注意到你的
pattern了吗?这是非常低效的。此外,术语可以是空格分隔的短语,因此您的单词边界方法将部分起作用,而无需先对术语进行排序。例如。如果您同时拥有Mercedes Benz和Mercedes,则永远不会匹配前者。 -
请解释你为什么选择
\w*(?<![A-Za-z-;:,/|])而不是普通的\b? -
只是为了确保像 Cars 这样的特殊字符旁边的术语;替换时考虑。
-
所以,基本上,
\b(?:term1|term2)\b应该在排序后工作。 -
意思是添加 \b(?:term1|term2)\b 作为模式的一部分?