numpy: 배열의 고유 값에 대한 가장 효율적인 주파수 수
/에서 배열의 고유 값에 대한 주파수 카운트를 얻는 효율적인 방법이 있는가?
이 선을 따라 다음과 같은 것이 있다.
x = array( [1,1,1,2,2,2,5,25,1,1] )
y = freq_count( x )
print y
>> [[1, 5], [2,3], [5,1], [25,1]]
(R 이용자들을 위해, 기본적으로, 나는 저 밖에 있는 R 이용자들을 찾고 있다.table()
함수 )
Numpy 1.9를 기준으로 가장 쉽고 빠른 방법은 단순히 사용하는 것인데, 현재 이 방법은 다음과 같다.return_counts
키워드 인수:
import numpy as np
x = np.array([1,1,1,2,2,2,5,25,1,1])
unique, counts = np.unique(x, return_counts=True)
print np.asarray((unique, counts)).T
다음과 같은 이점을 얻을 수 있다.
[[ 1 5]
[ 2 3]
[ 5 1]
[25 1]]
와의 빠른 비교.scipy.stats.itemfreq
:
In [4]: x = np.random.random_integers(0,100,1e6)
In [5]: %timeit unique, counts = np.unique(x, return_counts=True)
10 loops, best of 3: 31.5 ms per loop
In [6]: %timeit scipy.stats.itemfreq(x)
10 loops, best of 3: 170 ms per loop
을 보다.np.bincount
:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html
import numpy as np
x = np.array([1,1,1,2,2,2,5,25,1,1])
y = np.bincount(x)
ii = np.nonzero(y)[0]
그런 다음:
zip(ii,y[ii])
# [(1, 5), (2, 3), (5, 1), (25, 1)]
또는:
np.vstack((ii,y[ii])).T
# array([[ 1, 5],
[ 2, 3],
[ 5, 1],
[25, 1]])
또는 카운트와 고유 값을 조합할 수도 있다.
업데이트: 원래 답변에서 언급된 방법은 더 이상 사용되지 않으며, 대신 새로운 방법을 사용해야 한다.
>>> import numpy as np
>>> x = [1,1,1,2,2,2,5,25,1,1]
>>> np.array(np.unique(x, return_counts=True)).T
array([[ 1, 5],
[ 2, 3],
[ 5, 1],
[25, 1]])
원본 답변:
scipy.csi.profreq를 사용할 수 있다.
>>> from scipy.stats import itemfreq
>>> x = [1,1,1,2,2,2,5,25,1,1]
>>> itemfreq(x)
/usr/local/bin/python:1: DeprecationWarning: `itemfreq` is deprecated! `itemfreq` is deprecated and will be removed in a future version. Use instead `np.unique(..., return_counts=True)`
array([[ 1., 5.],
[ 2., 3.],
[ 5., 1.],
[ 25., 1.]])
나 역시 이것에 관심이 있어서 약간의 성과 비교를 했다(나의 애완동물 프로젝트인 관류도를 사용).결과:
y = np.bincount(a)
ii = np.nonzero(y)[0]
out = np.vstack((ii, y[ii])).T
가장 빠르다. (로그 스케일링에 유의하십시오.)
그래프를 생성할 코드:
import numpy as np
import pandas as pd
import perfplot
from scipy.stats import itemfreq
def bincount(a):
y = np.bincount(a)
ii = np.nonzero(y)[0]
return np.vstack((ii, y[ii])).T
def unique(a):
unique, counts = np.unique(a, return_counts=True)
return np.asarray((unique, counts)).T
def unique_count(a):
unique, inverse = np.unique(a, return_inverse=True)
count = np.zeros(len(unique), dtype=int)
np.add.at(count, inverse, 1)
return np.vstack((unique, count)).T
def pandas_value_counts(a):
out = pd.value_counts(pd.Series(a))
out.sort_index(inplace=True)
out = np.stack([out.keys().values, out.values]).T
return out
b = perfplot.bench(
setup=lambda n: np.random.randint(0, 1000, n),
kernels=[bincount, unique, itemfreq, unique_count, pandas_value_counts],
n_range=[2 ** k for k in range(26)],
xlabel="len(a)",
)
b.save("out.png")
b.show()
판다 모듈 사용:
>>> import pandas as pd
>>> import numpy as np
>>> x = np.array([1,1,1,2,2,2,5,25,1,1])
>>> pd.value_counts(x)
1 5
2 3
25 1
5 1
dtype: int64
이것은 단연코 가장 일반적이고 실행적인 해결책이다.; 이 해결책은 아직 게시되지 않았다.
import numpy as np
def unique_count(a):
unique, inverse = np.unique(a, return_inverse=True)
count = np.zeros(len(unique), np.int)
np.add.at(count, inverse, 1)
return np.vstack(( unique, count)).T
print unique_count(np.random.randint(-10,10,100))
현재 승인된 답변과는 달리, 그것은 (긍정적인 int만이 아니라) 정렬 가능한 모든 데이터 형식에서 작동하며, 최적의 성능을 가지고 있다; 유일한 중요한 비용은 np.unique에 의한 정렬에 있다.
numpy.bincount
아마 최선의 선택일 거야배열에 작은 밀도 정수 외에 다른 것이 포함되어 있는 경우 다음과 같이 포장을 하는 것이 유용할 수 있다.
def count_unique(keys):
uniq_keys = np.unique(keys)
bins = uniq_keys.searchsorted(keys)
return uniq_keys, np.bincount(bins)
예를 들면 다음과 같다.
>>> x = array([1,1,1,2,2,2,5,25,1,1])
>>> count_unique(x)
(array([ 1, 2, 5, 25]), array([5, 3, 1, 1]))
이미 답변이 끝났음에도 불구하고, 나는 다른 접근법을 제안한다.numpy.histogram
이러한 함수는 빈으로 그룹화된 원소의 주파수를 반환한다.
이 예에서는 숫자가 정수이기 때문에 주의하십시오.만약 그들이 실수를 하는 곳에 있다면, 이 해결책은 그렇게 잘 적용되지 않을 것이다.
>>> from numpy import histogram
>>> y = histogram (x, bins=x.max()-1)
>>> y
(array([5, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1]),
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.,
12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22.,
23., 24., 25.]))
오래된 질문이지만, 가장 빠른 것으로 판명된 나만의 해결책을 제공하고 싶다, 대신 보통을 사용한다.np.array
내 벤치 테스트에 기초하여 입력(또는 목록으로 먼저 전송)할 것.
너도 마주치면 확인해봐.
def count(a):
results = {}
for x in a:
if x not in results:
results[x] = 1
else:
results[x] += 1
return results
예를 들어,
>>>timeit count([1,1,1,2,2,2,5,25,1,1]) would return:
루프당 2.26µs의 3가지 장점인 100,000개의 루프
>>>timeit count(np.array([1,1,1,2,2,2,5,25,1,1]))
루프당 3: 8.8µs의 최고 루프 100,000개
>>>timeit count(np.array([1,1,1,2,2,2,5,25,1,1]).tolist())
루프당 5.85µs의 최대 3가지 루프 100,000개
반면 받아들여진 대답은 더디게, 그리고 더디게 대답할 것이다.scipy.stats.itemfreq
해결책은 더 나쁘다.
더 나중의 테스트는 공식화된 기대치를 확인하지 않았다.
from zmq import Stopwatch
aZmqSTOPWATCH = Stopwatch()
aDataSETasARRAY = ( 100 * abs( np.random.randn( 150000 ) ) ).astype( np.int )
aDataSETasLIST = aDataSETasARRAY.tolist()
import numba
@numba.jit
def numba_bincount( anObject ):
np.bincount( anObject )
return
aZmqSTOPWATCH.start();np.bincount( aDataSETasARRAY );aZmqSTOPWATCH.stop()
14328L
aZmqSTOPWATCH.start();numba_bincount( aDataSETasARRAY );aZmqSTOPWATCH.stop()
592L
aZmqSTOPWATCH.start();count( aDataSETasLIST );aZmqSTOPWATCH.stop()
148609L
아래 캐쉬 및 소규모 데이터 집합에 대규모 반복 테스트 결과에 영향을 미치는 기타 RAM 내 부작용에 대한 의견을 참조하십시오.
import pandas as pd
import numpy as np
x = np.array( [1,1,1,2,2,2,5,25,1,1] )
print(dict(pd.Series(x).value_counts()))
이렇게 하면: {1: 5, 2, 3, 5: 1, 25: 1}
독특한 비정수자를 세기 위해 - 이엘레코 후겐도른의 대답과 비슷하지만 상당히 빠른 (내 기계에 5인자)을 사용했다.weave.inline
결합하다numpy.unique
의 c-codeg가 있다.
import numpy as np
from scipy import weave
def count_unique(datain):
"""
Similar to numpy.unique function for returning unique members of
data, but also returns their counts
"""
data = np.sort(datain)
uniq = np.unique(data)
nums = np.zeros(uniq.shape, dtype='int')
code="""
int i,count,j;
j=0;
count=0;
for(i=1; i<Ndata[0]; i++){
count++;
if(data(i) > data(i-1)){
nums(j) = count;
count = 0;
j++;
}
}
// Handle last value
nums(j) = count+1;
"""
weave.inline(code,
['data', 'nums'],
extra_compile_args=['-O2'],
type_converters=weave.converters.blitz)
return uniq, nums
프로필 정보
> %timeit count_unique(data)
> 10000 loops, best of 3: 55.1 µs per loop
이엘레코의 순수함numpy
버전:
> %timeit unique_count(data)
> 1000 loops, best of 3: 284 µs per loop
참고
여기도 여분이 있고 (여기도)unique
또한 정렬을 수행함), 즉, 코드는 다음과 같이 입력하여 더욱 최적화될 수 있다.unique
c-code
다중주파수(즉, 배열 계수)
>>> print(color_array )
array([[255, 128, 128],
[255, 128, 128],
[255, 128, 128],
...,
[255, 128, 128],
[255, 128, 128],
[255, 128, 128]], dtype=uint8)
>>> np.unique(color_array,return_counts=True,axis=0)
(array([[ 60, 151, 161],
[ 60, 155, 162],
[ 60, 159, 163],
[ 61, 143, 162],
[ 61, 147, 162],
[ 61, 162, 163],
[ 62, 166, 164],
[ 63, 137, 162],
[ 63, 169, 164],
array([ 1, 2, 2, 1, 4, 1, 1, 2,
3, 1, 1, 1, 2, 5, 2, 2,
898, 1, 1,
import pandas as pd
import numpy as np
print(pd.Series(name_of_array).value_counts())
from collections import Counter
x = array( [1,1,1,2,2,2,5,25,1,1] )
mode = counter.most_common(1)[0][0]
각종 파이선 라이브러리에서 통계적 결과를 모두 제공하는 R의 순서()와 내림차순의 단순한 기능성이 없어지기 때문에 대부분의 간단한 문제들이 복잡해진다.그러나 만약 우리가 그러한 모든 통계적 순서와 비단뱀의 매개 변수를 팬더에서 쉽게 찾을 수 있다는 생각을 고안해 낸다면, 우리는 100개의 다른 장소를 찾는 것보다 더 빨리 결과를 얻을 수 있을 것이다.또한, R과 판다의 개발은 그들이 같은 목적으로 만들어졌기 때문에 함께 한다.이 문제를 해결하기 위해 나는 어디서든 나를 연결해 주는 다음 코드를 사용한다.
unique, counts = np.unique(x, return_counts=True)
d = {'unique':unique, 'counts':count} # pass the list to a dictionary
df = pd.DataFrame(d) #dictionary object can be easily passed to make a dataframe
df.sort_values(by = 'count', ascending=False, inplace = True)
df = df.reset_index(drop=True) #optional only if you want to use it further
이런 일이 일어나야 할 수 있는 그대로 해야 한다.
#create 100 random numbers
arr = numpy.random.random_integers(0,50,100)
#create a dictionary of the unique values
d = dict([(i,0) for i in numpy.unique(arr)])
for number in arr:
d[j]+=1 #increment when that value is found
또한, 이전의 '효율적으로 고유 요소를 세는 것'에 대한 게시물은, 내가 뭔가를 빠뜨리지 않는 한, 당신의 질문과 꽤 비슷한 것 같다.
'Programing' 카테고리의 다른 글
Vue.js에서 이스케이프되지 않은 HTML 표시 (0) | 2022.03.09 |
---|---|
Vuetify 내에서 여백 및 패딩 제거 (0) | 2022.03.09 |
Vuex 저장소 개체 반복 (0) | 2022.03.09 |
리액션 후크 "useContext"는 리액션 기능 구성 요소 또는 사용자 정의 리액션 후크 기능이 아닌 함수 "age"에서 호출된다. (0) | 2022.03.08 |
사용자가 브라우저를 다시 누른 후 마운트된 Vuejs를 트리거하지 않음 (0) | 2022.03.08 |