【问题标题】:Efficient way to mount a list of word occurences on Python [duplicate]在Python中挂载单词出现列表的有效方法[重复]
【发布时间】:2017-10-24 18:22:34
【问题描述】:

我想挂载一个数据结构,说明出现次数并以正确的顺序映射它们。

例如:

word_1 => 10 次出现

word_2 => 5 次出现

word_3 => 12 次出现

word_4 => 2 次出现

并且每个单词都有一个 id 来表示它:

kw2id = ['word_1':0, 'word_2':1, 'word_3':2, 'word_4': 3]

所以一个有序列表将是:

ordered_vocab = [2, 0, 1, 3]

例如我的代码是这样的...:

#build a vocabulary with the number of ocorrences
vocab = {}
count = 0
for line in open(DATASET_FILE):
    for word in line.split():
        if word in vocab:
            vocab[word] += 1
        else:
            vocab[word] = 1
    count += 1
    if not count % 100000:
        print(count, "documents processed")

我怎样才能有效地做到这一点?

【问题讨论】:

  • 那么,出现次数是如何存储的?我猜这是输入之一。你能清楚地定义样本输入吗?
  • 为什么不使用collections.Counter,然后用一些规则对键进行排序?

标签: python algorithm data-structures


【解决方案1】:

这就是 Counters 的用途:

from collections import Counter
cnt = Counter()

with open(DATASET_FILE) as fp:
    for line in fp.readlines():
        for word in line.split():
            cnt[word] += 1

或者(使用生成器更短更“漂亮”):

from collections import Counter

with open(DATASET_FILE) as fp:
    words = (word for line in fp.readlines() for word in line.split())
    cnt = Counter(words)

【讨论】:

  • 我怎样才能打印例如.. Counter obj 的前 3 个单词?
  • Nvm,只使用一个迭代......非常感谢,这解决了问题。
  • @denisCandido:不客气。
  • 但在那种情况下,这是一式三份的回答无数次......我在 2 分钟内找到了 3 个问答,内容相同。
  • ce n'est pa le but ultime。如果您已经看到这样的问题或简单的谷歌搜索找到 3 个点击,则您不应该回答(或者如果您的答案不同/更好/更新,则在原始问题中标记为欺骗和回答)。并非每次都有效,但有时有效:stackoverflow.com/questions/9072844/…
【解决方案2】:

这是你代码的一个稍微快一点的版本,很抱歉我不太了解 numpy,但也许这会有所帮助,enumeratedefaultdict(int) 是我所做的更改(你没有接受这个答案,只是想帮忙)

from collections import defaultdict

#build a vocabulary with the number of ocorrences
vocab = defaultdict(int)
with open(DATASET_FILE) as file_handle:
    for count,line in enumerate(file_handle):
        for word in line.split():
            vocab[word] += 1
        if not count % 100000:
            print(count, "documents processed")

另外,defaultdict(int) 从 0 开始的速度似乎是 Counter() 的两倍,因为 for 循环中的增量(运行 Python 3.44):

from collections import Counter
from collections import defaultdict
import time

words = " ".join(["word_"+str(x) for x in range(100)])
lines = [words for i in range(100000)]

counter_dict = Counter()
default_dict = defaultdict(int)

start = time.time()
for line in lines:
    for word in line.split():
        counter_dict[word] += 1
end = time.time()
print (end-start)

start = time.time()
for line in lines:
    for word in line.split():
        default_dict[word] += 1
end = time.time()
print (end-start)

结果:

5.353034019470215
2.554084062576294

如果您想对此声明提出异议,请参考以下问题:Surprising results with Python timeit: Counter() vs defaultdict() vs dict()

【讨论】:

    【解决方案3】:

    您可以使用 collection.Counter。 Counter 允许您输入一个列表,它会自动计算每个元素的出现次数。

    from collections import Counter
    l = [1,2,2,3,3,3]
    cnt = Counter(l)
    

    除了上述答案之外,您还可以做什么,它可以从文件中创建一个单词列表,并将 Counter 与列表一起使用,而不是手动遍历列表中的每个元素。请注意,如果您的文件与内存相比太大,则此方法不适合。

    【讨论】:

      【解决方案4】:

      字符串:

      >>> a = 'word_1 word_2 word_3 word_2 word_4'
      

      ID

      >>> d = {'word_1':0, 'word_2':1, 'word_3':2, 'word_4': 3}
      

      要生成字数:

      >>> s = dict(zip(a.split(), map(lambda x: a.split().count(x), a.split())))
      >>> s
      {'word_1': 1, 'word_2': 2, 'word_3': 1, 'word_4': 1}
      

      生成有序列表:

      >>> a = sorted(s.items(), key=lambda x: x[1], reverse=True)
      >>> ordered_list = list(map(lambda x: d[x[0]], a ))
      >>> ordered_list
      [1, 0, 2, 3]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-14
        • 2021-02-05
        • 2019-06-01
        • 2021-01-08
        • 1970-01-01
        • 2021-05-09
        相关资源
        最近更新 更多