3

所以这是我的问题。我有一个非常大的 csv 文件,它有 3 列。第一列是唯一 ID。第二列是一个字符串,它是一个英文句子。第三列是一串单词标签,描述第二列中的句子(通常是 3 个标签,最多 5 个)。这是一个例子。

id | sentence                       | tags
1  | "people walk dogs in the park" | "pet park health"
2  | "I am allergic to dogs"        | "allergies health"

我想要做的是找到标记词与句子中单词的所有共现。因此,上述示例的所需输出看起来像这样。

("walk","pet"),1
("health","dogs"),2
("allergies","dogs"),1
etc...

其中第一个条目是一个词对(第一个来自句子,第二个是标签词),然后是它们共同出现的次数。

我想知道最好的方法是什么。我在想也许我可以想出一个 python 字典,其中键是标签词,值是标签词出现的一组 id。我可以对所有句子中出现的所有单词做同样的事情(在删除停用词之后)。然后我可以计算这两个单词的每个组合在两个集合的交集中的 id 数量,这会给我它们同时出现的次数。

但是,这似乎需要很长时间(巨大的 csv 文件!)。我也可能内存不足。谁能想到更好的方法来做到这一点。也许将文件导入数据库并运行某种查询?

4

1 回答 1

6

我认为使用itertools.product()collections.Counter()很容易:

import csv
from itertools import product
from collections import Counter

rdr = csv.reader(open(r"data.csv"), quotechar='"',delimiter='|')
c = Counter((x, y) for _, a, b in rdr for x, y in product(a.split(), b.split()))

至于处理大文件,我认为您可以尝试某种 map-reduce - 逐行读取 csv 并将所有组合保存到另一个文件中:

with open(r"data.csv") as r, open(r"data1.csv", "w") as w:
    rdr = csv.reader(r, quotechar='"', delimiter='|')
    for _, a, b in rdr:
        for x, y in product(a.split(), b.split()):
            w.write("{},{}\n".format(x, y))

下一步是读取第二个文件并创建计数器:

with open(r"c:\temp\data1.csv") as r:
    for l in r:
        c[l.rstrip('\n')] += 1

更新我已经开始看到是否有任何用于 Python 的 map-reduce 框架。这是谷歌搜索的第一个链接 - Disco map-reduce framework。实际上它有一个教程,展示了如何创建和运行一个计算单词的迪斯科作业 - 我认为它可能对你有用(至少我会去试一试:))。还有一个 - https://github.com/michaelfairley/mincemeatpy

于 2013-09-14T19:17:35.393 回答