2017-02-27 1 views
0

매우 큰 numpy.array의 정수가 있습니다. 각 정수는 [0, 31]입니다.numpy 배열에서 정수 x 바로 다음에 정수 y가 얼마나 자주 발생하는지 계산합니다.

b 바로 a 후에 발생 빈도 범위 [0, 31] (예컨대 [0, 1], [7, 9], [18, 0])의 정수 (a, b)의 각 쌍에 카운트 싶습니다.

이렇게하면 (32, 32) 개의 행렬을 얻을 수 있습니다.

numpy를 사용하여 효율적인 방법을 찾고 있습니다. 원시 파이썬 루프는 너무 느립니다.

답변

2

여기에 내가 (9) 대신 (31)의 최대 값을 사용합니다,

가 읽을 수있는 예를 쉽게하기 위해 ... 하나의 방법입니다 :

In [181]: counts = np.zeros((maxval+1, maxval+1), dtype=int) 
,536,913 :
In [179]: np.random.seed(123) 

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

는 처음에 모든 0 결과를 만들기

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 

우리가 할 수있다 : 중복 적절하게 계산되었는지 63,210

지금 있도록 numpy.add.at를 사용하여, 각각의 좌표 쌍 1을 추가 다음 표현식을 사용하여 확인하십시오.

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 

배열이 다차원 인 경우 먼저 평면화하거나 위의 코드를 약간 수정해야합니다.

In [178]: maxval = 9 

는 예를 들어 임의의 입력을 확인 :

+0

감사합니다. 답 : 고맙습니다. 해결책은 훌륭하지만 실제로는 원시보다 느립니다. 파이썬 루프. – valentin

관련 문제