我有一个大型数据集,它包含与真实网站中的照片相对应的标签(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)))
如何加快速度?
谢谢!
答案 0 :(得分:2)
x.count(tag) for x in data
此部分会循环显示所有数据中的所有标记。对每个标记执行此操作一次。这是很多不必要的循环。使用Counter
或defaultdict(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
。