Python:从两个大数组中计算出现次数

Python:从两个大数组中计算出现次数,python,Python,我有下面的脚本,它计算从一个数组到另一个数组的值的出现次数 array_1 = [1,2,0,5,7,0] array_2 = [1,0,1,1,9,6] # on array 2 there are 3 occurrence of 1, and 1 occurrence of zero, but because there is another zero at array_1 add 1 more. 3+2 = 5 for r in array_1: total_count = t

我有下面的脚本,它计算从一个数组到另一个数组的值的出现次数

array_1 = [1,2,0,5,7,0]
array_2 = [1,0,1,1,9,6]
# on array 2 there are 3 occurrence of 1, and 1 occurrence of zero, but because there is another zero at array_1 add 1 more. 3+2 = 5

for r in array_1:
     total_count = total_count + array_2.count(r)

print("total sum: {0}".format(total_count))
处理小数组大小时可以,但当数组大小增加时(对于
array_1
为100万,对于
array_2
为100万)。有没有更好的办法


很抱歉造成混淆,我更新了一点问题。

使用
集合
而不是列表:

array1_set = set(array_1)
total_count = sum(1 for x in array_2 if x in array1_set)
注:速度快五倍

你可以用。它会更快,因为它只迭代列表中的一个

from collections import Counter

array_1 = [1,2,0,5,7]
array_2 = [1,0,1,1,9]

c = Counter(array_1)
total_count = sum(c[x] for x in array_2)

print("total sum: {0}".format(total_count))

如果数组1中有大量重复的数字,则可以通过缓存它们(以{number:count}的形式构建dict)来节省时间。典型的缓存功能如下所示:

counts = {}
def get_count(number):
    if number in counts:
        return counts[number]
    else:
        count = your_counting_function(number)
        counts[number] = count
        return count
此行为打包到装饰器中,因此功能可以简化为:

from functools import lru_cache

@lru_cache(maxsize=None)
def get_count(number):
    return array_2.count(number)
如果在数组1中有少量不同的值,例如,整数1到10的随机混洗,这将是一种非常有效的方法。这有时被称为具有低基数(基数为10)的数组_1

如果你有一个很高的基数(比如在一个1M值的数组中有900k个不同的值),一个更好的优化方法是在你开始之前预先计算所有的计数,这样你只需要在数组_2上进行一次遍历。Dict查找比在整个数组中计数快得多

array_2_counts = {}
for number in array_2:
    if number in counts:
        array_2_counts[number] += 1
    else:
        array_2_counts[number] = 1


total_count = 0
for number in array_1:
    total_count += array_2_counts[number]
Python也有一个内置的解决方案!可以使用以下方法简化上述代码:


为什么array2不也有1个9的出现?因为9不在数组1中?我需要使用数组1来计算数组2中重复出现的数字。不要接受我的解决方案,使用Netwave中的解决方案。我需要重新计算重复的数字,但结果与我需要的不同。@Led,你是指
数组1
中重复的数字吗?@Led我认为你不理解“正确”这个词的含义. 结果与您需要的结果有何不同?是的,必须重新计算重复的数组1和数组2。我要补充的是,在循环中调用
count
需要为每个
count
调用单独传递列表,这就是
collections.Counter
更快的原因。@Megalng是的,他的答案更快,但是我有大量的数组,你的结果是正确的。谢谢你的详细说明,但我会选择Megalng的答案,因为他/她先发布了。非常感谢。
from collections import Counter

array_2_counter = new Counter(array_2)
for number in array_1:
    total_count += array_2_counter[number]