string - 用字典替换子字符串的最快方法(在大型数据集上)

标签 string pandas numpy replace substring

我有 10M 文本(适合 RAM)和一种 python 字典:

"old substring":"new substring"

字典的大小约为 15k 个子字符串。

我正在寻找用字典替换每个文本的最快方法(在每个文本中查找每个“旧子字符串”并将其替换为“新子字符串”)。

源文本在 Pandas 数据框中。
现在我已经尝试过这些方法:

1) 在循环中用 reduce 和 str replace 替换(~120 行/秒)
replaced = []
for row in df.itertuples():
    replaced.append(reduce(lambda x, y: x.replace(y, mapping[y]), mapping, row[1]))

2) 在循环中使用简单的替换函数(“映射”是 15k 字典)(~160 行/秒):
def string_replace(text):
    for key in mapping:
        text = text.replace(key, mapping[key])
    return text

replaced = []
for row in tqdm(df.itertuples()):
    replaced.append(string_replace(row[1]))

此外 .iterrows() 的工作速度比 .itertuples() 慢 20%

3)在系列上使用应用(也~160行/秒):
replaced = df['text'].apply(string_replace)

以这样的速度处理整个数据集需要数小时。

任何人都有这种大规模子串替换的经验?有没有可能加快速度?它可能很棘手或丑陋,但必须尽可能快,没有必要使用 Pandas 。

谢谢。

更新:
玩具数据检查想法:
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

最佳答案

我再次克服了这个问题,发现了一个很棒的库,名为 flashtext .

1000 万条记录和 15000 个词汇的加速大约是 x100(比我第一篇文章中的正则表达式或其他方法快一百倍)!

非常容易使用:

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_boundaries 属性灵活适应不同的语言。

此处使用的基于 Trie 的搜索提供了惊人的加速。

关于string - 用字典替换子字符串的最快方法(在大型数据集上),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46238378/

相关文章:

python-3.x - 如何将未命名的列设置为索引?

python - 如何根据一列从 2 个数据帧中获取不匹配的数据。 ( Pandas )

python - 为什么使用 str(df[col]) 会导致代码仅与单个记录相关?

python - 在 Python 中排序的最快方法(没有 cython)

python - np 数组是不可变的 - "assignment destination is read-only"

python - 何时使用 np.quantile 和 np.percentile?

C - 连接字符串的所有头部

regex - 什么时候最好在基本的字符串拆分/子字符串化上使用正则表达式?

string - 在 bash 中使用随机可打印字符串创建特定大小的文件

string - Common Lisp 中字符串和数字的核心区别是什么?