2017-10-26 1 views
0

나는 다소 큰 숫자 입력 배열 인 ~30 million 항목으로 파이썬으로 빈도 테이블을 만드는 효율적인 방법을 구현하려고합니다. 현재 for-loop을 사용하고 있지만 너무 오래 걸립니다.효율적으로 배열의 항목 수에 대한 빈 테이블을 만드는 방법 Python

입력 양식

Y = np.array([4, 4, 4, 6, 6, 7, 8, 9, 9, 9..... etc]) 

의 순서 numpy array 내가 형태의 출력을 가지고 싶다 :

Z = {4:3, 5:0, 6:2, 7:1,8:1,9:3..... etc} (as any data type) 

현재 나는 다음과 같은 구현을 사용하고 있습니다 :

Z = pd.Series(index = np.arange(Y.min(), Y.max())) 

for i in range(Y.min(), Y.max()): 
    Z[i] = (Y == i).sum() 

이 방법을 사용하지 않고 빠른 방법이 있습니까 iterating 루프를 통해? 도움을 주셔서 감사합니다. 이전에 요청한 경우 미안합니다.

+0

사용 (https://docs.python.org/3 /library/collections.html#collections.Counter) –

+0

사전을 쿼리 한 시간부터 계산 하시겠습니까? 또는 특정 시간에 스냅 샷을 원하십니까? – mypetlion

답변

3

간단히 수집 모듈의 카운터를 사용하면됩니다. 귀하의 테스트 케이스를 실행 한 아래 코드를 참조하십시오.

import numpy as np 
from collections import Counter 
Y = np.array([4, 4, 4, 6, 6, 7, 8, 9, 9, 9,10,5,5,5]) 
print(Counter(Y)) 

그것은 다음과 같은 출력

Counter({4: 3, 9: 3, 5: 3, 6: 2, 7: 1, 8: 1, 10: 1}) 

쉽게 더이 객체를 사용했다. 이게 도움이 되길 바란다.

1

numpy.unique가 해결책이라고 생각합니다.

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.unique.html

import numpy as np 
t = np.random.randint(0, 1000, 100000000) 
print(np.unique(t, return_counts=True)) 

이 나를 위해 4 ~ 초 정도 걸립니다. collections.Counter 접근에는 약 10 초가 소요됩니다.

그러나 numpy.unique는 배열의 빈도를 반환하고 collections.Counter는 사전을 반환합니다. 편의성은 최대입니다.

편집. 다른 게시물에 대해서는 언급 할 수 없으므로 @lomereiters 솔루션은 번개가 빠른 (선형) 것으로 받아 들여야합니다. 당신의 입력 배열 x이 정렬되어있는 경우

+0

나는 그렇지 않다고 생각한다. 카운터가 더 좋습니다. – erip

+2

OP에서 "(모든 데이터 유형으로)"를 보았고 배열을 사용할 수 있다고 생각했습니다. 이것이 왜 그렇게 좋지 않은지 다른 이유가 있습니까? –

+0

'그리고 나는 다음과 같은 형식의 출력을 원합니다 :' – erip

1

, 당신은 선형 시간에 카운트를 얻기 위해 다음을 수행 할 수 [? collections.counter]

diff1 = np.diff(x) 
# get indices of the elements at which jumps occurred 
jumps = np.concatenate([[0], np.where(diff1 > 0)[0] + 1, [len(x)]]) 
unique_elements = x[jumps[:-1]] 
counts = np.diff(jumps) 
관련 문제