首页 > 解决方案 > 获取文件中提及特定关键字的行

问题描述

我有两个文件,keywords_file (5MB) 每行包含一个单词。这是一个示例:

prénom
pseudonyme
surnom
accès aux origines
puissance paternelle
droit de l’enfant
devoir de protection
droit à la survie
travail des enfants
obligation scolaire
assistance éducative
mauvais traitements
filiation adultérine

r_isa (205MB) 包含共享“isa”关系的单词。这是一个示例,其中\t表示文字制表符:

égalité de Parseval\tformule_0.9333\tégalité_1.0
filiation illégitime\tfiliation_1.0
Loi reconnaissant l'égalité\tloi_1.0
égalité entre les sexes\tégalité_1.0
liberté égalité fraternité\tliberté_1.0

这意味着,“égalité de Parseval”是得分为 0.9333 的“公式”,得分为 1 的“égalité”。等等。

我想从 r_isa 文件中获取与关键字文件中提到的关键字具有上位词关系的单词。这是我所做的:

keywords = pd.read_csv("keywords_file.txt", sep="\t",encoding = 'utf8', header=None)
with open("r_isa.txt",encoding="utf-8") as openfile:
    for line in openfile:
        for k in keywords[0]:
            if k in line:
                file = open('isa.txt','a', encoding='utf-8')
                file.write(("".join(line) + "\n"))
                file.close()

这整夜不停地运行。我猜一定有什么不对劲。有什么帮助吗?

PS:我想添加这样的正则表达式:

...
    for k in keywords[0]:
        if re.search(r'\b' + k + r'\b', line):
...

查找每一行上的确切单词,但这给我带来了以下错误,所以我将其保留为现在:

error: missing ), unterminated subpattern at position 69

标签: pythonpandas

解决方案


可能主要的瓶颈是重复打开以在紧密循环内追加。每次写入文件时,操作系统都需要打开文件并寻找到最后。如果您需要多个编写器来访问文件的末尾,则可以将每个编写器运行并输出到一个单独的文件,然后在所有编写器完成后合并结果文件。

我也有点怀疑你阅读文件的顺序。显然原始r_isa.txt文件更大,但如果它包含的行数少于keywords.txt文件,则可能切换它们。通常,尝试将较小的数据集读入内存,然后循环遍历较大的文件,一次一行。

这是一个完全没有 Pandas 的尝试。使用它可能没有什么问题,但它在这里也没有真正提供太多价值。

我也改用正则表达式;我不清楚这是否会提高性能,但至少它应该向您展示如何实现这一点,以便您可以衡量和比较。

import re

keywords = []
with open("keywords_file.txt") as kwfile:
    keywords = [line.rstrip('\n') for line in kwfile]

regex = re.compile(r'\b(?:' + '|'.join(keywords) + r')\b')

with open("r_isa.txt") as readfile, open('isa.txt', 'w') as writefile:
    for line in readfile:
        firstfield = line.split('\t')[0]
        m = regex.match(firstfield)
        if m:
            writefile.write(line)

正则表达式适用于查找子字符串匹配和变体;如果您只是希望将第一个字段逐字存在的每一行作为关键字文件中的一行,这几乎肯定会更快:

    for line in readfile:
        firstfield = line.split('\t')[0]
        if firstfield in keywords:
            writefile.write(line)

然后当然取出import reregex分配。也许也可以转换keywordsset().


推荐阅读