在python中存储ngram(字数可变的字符串)的最快方法

2024-06-16 18:41:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个输入文件,由数字行和字序列组成,结构如下:

\1-grams:
number   w1    number
number   w2    number
\2-grams:
number   w1 w2   number
number   w1 w3   number
number   w2 w3   number
\end\

我想以这样一种方式存储单词序列(所谓的n-gram),这样我就可以很容易地为每个唯一的n-gram检索两个数字。我现在要做的是:

^{pr2}$

这样我就可以很容易很快地找到序列s='w1 w2'的数字:

all[2][s]

问题是这个存储过程相当慢,尤其是当有大量(大于100k)的n-gram时,我想知道是否有一种更快的方法可以在不降低访问速度的情况下实现相同的结果。我在做一些不太理想的事情吗?我在哪里可以改进?在

提前谢谢你

乔里斯


Tags: 文件number方式序列数字单词结构w1
3条回答

我会尝试减少regexp搜索。在

值得考虑的是:

  • 将所有数据存储在一个字典中可能会加快速度;具有额外层的数据层次结构没有帮助,可能会与直觉相反。

  • 存储元组可以避免调用.format()

  • 在CPython中,函数中的代码比全局代码更快。

可能是这样的:

def load(filename):
    ngrams = {}
    for line in open(filename):
        if line[0] == '\\':
            pass  # just ignore all these lines
        else:
            first, rest = line.split(None, 1)
            middle, last = rest.rsplit(None, 1)
            ngrams[middle] = first, last
    return ngrams

ngrams = load("ngrams.txt")

我想存储int(first), int(last),而不是{}。这会加快访问速度,但会减慢加载时间。所以这取决于你的工作量。在

我不同意johnthexii的观点:只要数据集适合内存,用Python执行此操作应该比与数据库(甚至是sqlite)交谈快得多。(如果您使用数据库,这意味着您可以执行一次加载,而不必重复加载,因此sqlite可能最终完全符合您的需要,但不能使用:memory:database执行此操作。)

就个人而言,我会使用indexes迁移到数据库(sqllite3内置于python中)。索引使查询速度更快。Python还支持in memory sqllite databases。在

You can also supply the special name :memory: to create a database in RAM.

关于代码的优化。在

1)在循环之前编译正则表达式。请参阅帮助重新编译. 在

2)尽可能避免使用正则表达式。例如,可以通过简单的字符串比较检查前缀为数字的“-grams”字符串

相关问题 更多 >