如何提高大型数据集中Python计算的速度?

时间:2013-12-09 07:45:19

标签: python performance

我有一个大型数据集,它包含与真实网站中的照片相对应的标签(500 000条记录,每条记录至少包含一个标签)

示例:

TAG1

tag1 tag2 tag3

tag1 tag12 tag99

依此类推,500000次

我尝试根据数据集中每个标记的出现次数计算标记的权重。对于500行,代码运行良好(0.1秒),但对于整个数据,它需要数小时和数小时(超过8),即使对于PyPy

我认为我做错了什么并且使用Python效率低下。这是计算权重的代码:

for i, photo in enumerate(data):
  for j, tag in enumerate(photo):   
    if (tag not in tag_set):
      tag_set.append(tag)
      tag_w.append(log(len(data)) - log(sum(x.count(tag) for x in data)))

如何加快速度?

谢谢!

3 个答案:

答案 0 :(得分:2)

x.count(tag) for x in data

此部分会循环显示所有数据中的所有标记。对每个标记执行此操作一次。这是很多不必要的循环。使用Counterdefaultdict(int)对代码进行一次计数。如果Counter仍然很慢,defaultdict(int)可能更快,或者甚至只是一个普通的词典。我将使用Counter

import collections
import itertools
tag_counts = collections.Counter(itertools.chain.from_iterable(data))
tag_to_weight_dict = {tag: weight_function(count)
                      for tag, count in tag_counts.items()}

答案 1 :(得分:0)

这会更快,因为它不会重复每个标记的计数操作:

from math import log
tag_counts = {}
tag_weights = {}

for photo in data:
    for tag in photo:
        tag_counts[tag] = tag_counts.get(tag, 0) + 1

for tag, count in tag_counts.items():
    tag_weights[tag] = log(len(data)) - log(count)

答案 2 :(得分:0)

如果我理解正确,您可以使用逗号分隔的值,每行一个文件 并且您想要全局计算每个标记出现的频率,然后计算权重 每个标签都基于您的全局标记。

正如其他人指出你在代码的最后一行有一个多余的操作。

如上所述,您可以先使用collections.Counter计算。 如果按键数量巨大,您可以通过使用来加快速度 numpy.array

data_counted = collections.Counter([tag for photo in data for tag in photo])
data_vec = numpy.array([data_counted[k] for k in data_counted.keys()])
weights = numpy.subtract(log(len(data)), numpy.log(data_vec))

以上并没有真正保留data_counted中键的顺序,但在那里 可能是一种使用散列函数的方法。 或者完全跳过Counter步骤并将所有内容直接加载到numpy.array