String 用字典替换子字符串的最快方法(在大型数据集上)
我有1000万个文本(适合RAM)和一本python字典:String 用字典替换子字符串的最快方法(在大型数据集上),string,pandas,numpy,replace,substring,String,Pandas,Numpy,Replace,Substring,我有1000万个文本(适合RAM)和一本python字典: "old substring":"new substring" 字典的大小约为15k子字符串 我正在寻找用dict替换每个文本的最快方法(找到每个文本中的每个“旧子字符串”,并用“新子字符串”替换它) 源文本在数据框中。 目前,我已经尝试了以下方法: 1) 使用reduce和str Replace在循环中替换(~120行/秒) 2) 具有简单替换功能的循环中(“映射”是15k指令)(~160行/秒): 而且.iterrows()的工作
"old substring":"new substring"
字典的大小约为15k子字符串
我正在寻找用dict替换每个文本的最快方法(找到每个文本中的每个“旧子字符串”,并用“新子字符串”替换它)
源文本在数据框中。
目前,我已经尝试了以下方法:
1) 使用reduce和str Replace在循环中替换(~120行/秒)
2) 具有简单替换功能的循环中(“映射”是15k指令)(~160行/秒):
而且.iterrows()的工作速度比.itertuples()慢20%
3) 在系列上使用“应用”(也可约160行/秒):
以这样的速度处理整个数据集需要几个小时
有人有过这种大规模子串替换的经验吗?有可能加快速度吗?这可能是棘手的或丑陋的,但必须尽可能快,没有必要使用熊猫
谢谢
更新:
检查想法的玩具数据:
df = pd.DataFrame({ "old":
["first text to replace",
"second text to replace"]
})
mapping = {"first text": "FT",
"replace": "rep",
"second": '2nd'}
预期结果:
old replaced
0 first text to replace FT to rep
1 second text to replace 2nd text to rep
我想您正在寻找df上的正则表达式替换,即 如果您有字典,则将其作为参数传递
d = {'old substring':'new substring','anohter':'another'}
对于整个数据帧
df.replace(d,regex=True)
对于系列
df[columns].replace(d,regex=True)
范例
df = pd.DataFrame({ "old":
["first text to replace",
"second text to replace"]
})
mapping = {"first text": "FT",
"replace": "rep",
"second": '2nd'}
df['replaced'] = df['old'].replace(mapping,regex=True)
一种解决方案是将字典转换为a,并编写代码,以便只传递一次修改后的文本 基本上,您可以一次遍历文本和trie一个字符,一旦找到匹配项,就可以替换它
当然,如果你还需要对已经替换的文本进行替换,这就更难了。我再次克服了这个问题,找到了一个很棒的库,名为 在10M记录和15k词汇表上的加速约为x100(比我第一篇文章中的regexp或其他方法快一百倍) 非常容易使用:
df = pd.DataFrame({ "old":
["first text to replace",
"second text to replace"]
})
mapping = {"first text": "FT",
"replace": "rep",
"second": '2nd'}
import flashtext
processor = flashtext.KeywordProcessor()
for k, v in mapping.items():
processor.add_keyword(k, v)
print(list(map(processor.replace_keywords, df["old"])))
结果:
['FT to rep', '2nd text to rep']
如果需要,还可以使用processor.non_word_bounders属性灵活地适应不同的语言
这里使用的基于Trie的搜索速度惊人 检查。谢谢Wiktor,我现在看到了regexp=True的想法,但它比头条文章中的简单方法慢得多。你可以直接把字典递给我谢谢。不幸的是,这是一种慢得多的方法~每秒100行。@AlexeyTrofimov Try
regex=False
@cᴏʟᴅsᴘᴇᴇᴅ 他想替换字符串的子字符串。@Bharathshetty简单的替换不需要正则表达式
df = pd.DataFrame({ "old":
["first text to replace",
"second text to replace"]
})
mapping = {"first text": "FT",
"replace": "rep",
"second": '2nd'}
df['replaced'] = df['old'].replace(mapping,regex=True)
df = pd.DataFrame({ "old":
["first text to replace",
"second text to replace"]
})
mapping = {"first text": "FT",
"replace": "rep",
"second": '2nd'}
import flashtext
processor = flashtext.KeywordProcessor()
for k, v in mapping.items():
processor.add_keyword(k, v)
print(list(map(processor.replace_keywords, df["old"])))
['FT to rep', '2nd text to rep']