2017-02-27 57 views
0

我有一个非常大的整数numpy.array,其中每个整数的范围是[0, 31]计算整数y在numpy数组中整数x之后的频率

我想计数,对于在范围[0, 31](例如[0, 1], [7, 9], [18, 0])每对整数(a, b)的频率ba之后发生。

这会给我一个(32, 32)计数矩阵。

我正在寻找一种有效的方式来做到这一点与numpy。原始的python循环会太慢。

回答

2

这里有一种方法......

为了使示例更容易阅读,我将使用的9,而不是31最大值:

In [178]: maxval = 9 

做了例如随机输入:

In [179]: np.random.seed(123) 

In [180]: x = np.random.randint(0, maxval+1, size=100) 

创建的结果,最初所有0:

In [181]: counts = np.zeros((maxval+1, maxval+1), dtype=int) 

现在加入1到每个坐标对,使用numpy.add.at,以确保重复的系统正确计算:

In [182]: np.add.at(counts, (x[:-1], x[1:]), 1) 

In [183]: counts 
Out[183]: 
array([[2, 1, 1, 0, 1, 0, 1, 1, 1, 1], 
     [2, 1, 1, 3, 0, 2, 1, 1, 1, 1], 
     [0, 2, 1, 1, 4, 0, 2, 0, 0, 0], 
     [1, 1, 1, 3, 3, 3, 0, 0, 1, 2], 
     [1, 1, 0, 1, 1, 0, 2, 2, 2, 0], 
     [1, 0, 0, 0, 0, 0, 1, 1, 0, 2], 
     [0, 4, 2, 3, 1, 0, 2, 1, 0, 1], 
     [0, 1, 1, 1, 0, 0, 2, 0, 0, 3], 
     [1, 2, 0, 1, 0, 0, 1, 0, 0, 0], 
     [2, 0, 2, 2, 0, 0, 2, 2, 0, 0]]) 

例如,次6的数目随后用1是

In [188]: counts[6, 1] 
Out[188]: 4 

我们可以用下面的表达式来验证:

In [189]: ((x[:-1] == 6) & (x[1:] == 1)).sum() 
Out[189]: 4 
+0

这是一个非常优雅的解决方案。虽然我需要调查这个numpy函数实际上是如何工作的,以了解发生了什么! – valentin

0

您可以将numpy的内置diff例程与布尔数组一起使用。

import numpy as np  

test_array = np.array([1, 2, 3, 1, 2, 4, 5, 1, 2, 6, 7]) 
a, b = (1, 2) 

sum(np.bitwise_and(test_array[:-1] == a, np.diff(test_array) == b - a)) 
# 3 

如果您的数组是多维的,您需要首先对其进行平整或对上述代码进行一些小修改。

+0

谢谢你的回答:)即使你的解决方案是优雅的,它实际上比生python循环。 – valentin