पायथन में एक ndarray में कुछ आइटम की घटना की गणना कैसे करें?


376

अजगर में, मैं एक ndarray है y जो के रूप में मुद्रित हैarray([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

मैं गिनने की कोशिश कर रहा हूँ कि इस सरणी में कितने 0s और कितने 1s हैं।

लेकिन जब मैं टाइप करता हूं y.count(0)या y.count(1), यह कहता है

numpy.ndarray वस्तु की कोई विशेषता नहीं है count

मुझे क्या करना चाहिए?


8
क्या आप राशि और लंबाई फ़ंक्शन का उपयोग नहीं कर सकते हैं, क्योंकि आपके पास केवल इक्के और शून्य हैं?
कोडिंगइन्थैरिन

इस मामले में, बस उपयोग करना भी संभव है numpy.count_nonzero
मोंग एच। एनजी

जवाबों:


610
>>> a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
>>> unique, counts = numpy.unique(a, return_counts=True)
>>> dict(zip(unique, counts))
{0: 7, 1: 4, 2: 1, 3: 2, 4: 1}

गैर-खस्ता तरीका :

का उपयोग करें collections.Counter;

>> import collections, numpy

>>> a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
>>> collections.Counter(a)
Counter({0: 7, 1: 4, 3: 2, 2: 1, 4: 1})

3
यही कारण है कि हो सकता है `` `अद्वितीय, मायने रखता है = numpy.unique (क, return_counts = सच) dict (ज़िप (अद्वितीय, मायने रखता है))` ``
टुकड़ों में

25
यदि आप डिक्शनरी चाहते हैं,dict(zip(*numpy.unique(a, return_counts=True)))
सेपो एनारवी

2
क्या होगा अगर मैं चर को निर्दिष्ट किए बिना सरणी के प्रत्येक अद्वितीय तत्वों की घटनाओं की संख्या तक पहुंचना चाहता हूं - मायने रखता है। उस पर कोई संकेत?
साजिस 997

मेरे पास @ sajis997 जैसा ही लक्ष्य है। मैं एक समूह में एक समुच्चय समारोह के रूप में 'काउंट' का उपयोग करना चाहता हूं
p_sutherland

1
एक बहुत बड़े सरणी (~ 30Gb) के लिए दोनों तरीकों का उपयोग करने की कोशिश की। Numpy विधि स्मृति से बाहर भाग गई जबकि collections.Counterठीक काम किया
इवान नोविकोव

252

उपयोग के बारे में क्या numpy.count_nonzero, कुछ पसंद है

>>> import numpy as np
>>> y = np.array([1, 2, 2, 2, 2, 0, 2, 3, 3, 3, 0, 0, 2, 2, 0])

>>> np.count_nonzero(y == 1)
1
>>> np.count_nonzero(y == 2)
7
>>> np.count_nonzero(y == 3)
3

20
यह उत्तर सबसे ऊपर वाले के साथ बेहतर लगता है।
एलेक्स

1
मुझे नहीं लगता कि यह numpy.ndarrayओपी मूल रूप से पूछे जाने के लिए काम करेगा ।
लीयू

5
@Lyu - y इस उत्तर में एक np.ndarray है। इसके अलावा - सबसे अगर सभी np.something कार्य समस्या के बिना ndarrays पर काम करते हैं।
mmagnuski

132

व्यक्तिगत रूप से, मैं इसके लिए जाऊंगा: (y == 0).sum()और(y == 1).sum()

उदाहरण के लिए

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
num_zeros = (y == 0).sum()
num_ones = (y == 1).sum()

1
यह निश्चित रूप से पढ़ने में सबसे आसान है। सवाल जो सबसे तेज़ है, और सबसे अधिक अंतरिक्ष कुशल है
नाथन

शायद खाँसी कम जगह से अधिक कुशल। numpy.count_nonzero (y == 0), क्योंकि यह वेक्टर का मूल्यांकन करता है (y == 0)
श्रीधर थियागराजन

मुझे यह पसंद है क्योंकि matlab / octave के समान हैsum( vector==value )
ePi272314

39

अपने मामले के लिए आप भी numpy.bincount में देख सकते हैं

In [56]: a = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

In [57]: np.bincount(a)
Out[57]: array([8, 4])  #count of zeros is at index 0 : 8
                        #count of ones is at index 1 : 4

यह कोड मेरे द्वारा प्रयोग किए गए बड़े सरणियों के लिए सबसे तेज़ समाधानों में से एक हो सकता है। सूची के रूप में परिणाम प्राप्त करना एक बोनस है, भी। Thanx!
यंग्सअप किम

और अगर 'a' एक n- डायमेंशनल ऐरे है, तो हम बस इस्तेमाल कर सकते हैं: np.bincount (np.reshape (a, ansize))
Ari

21

अपनी सरणी yको सूची में बदलें lऔर फिर करें l.count(1)औरl.count(0)

>>> y = numpy.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>> l = list(y)
>>> l.count(1)
4
>>> l.count(0)
8 

19
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

यदि आप जानते हैं कि वे सिर्फ 0और 1:

np.sum(y)

आप लोगों की संख्या देता है। np.sum(1-y)शून्य देता है।

थोड़ी सामान्यता के लिए, यदि आप गिनना चाहते हैं 0और शून्य नहीं (लेकिन संभवतः 2 या 3):

np.count_nonzero(y)

नॉनवेज का नंबर देता है।

लेकिन अगर आपको कुछ अधिक जटिल चाहिए, तो मुझे नहीं लगता कि सुन्न एक अच्छा countविकल्प प्रदान करेगा । उस स्थिति में, संग्रह पर जाएं:

import collections
collections.Counter(y)
> Counter({0: 8, 1: 4})

यह एक तानाशाही की तरह व्यवहार करता है

collections.Counter(y)[0]
> 8

13

यदि आप वास्तव में जानते हैं कि आप किस नंबर की तलाश कर रहे हैं, तो आप निम्नलिखित का उपयोग कर सकते हैं;

lst = np.array([1,1,2,3,3,6,6,6,3,2,1])
(lst == 2).sum()

आपके ऐरे में कितनी बार 2 हुआ है।


8

ईमानदारी से मुझे पांडा श्रृंखला या डेटाफ़्रेम में बदलना सबसे आसान लगता है:

import pandas as pd
import numpy as np

df = pd.DataFrame({'data':np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])})
print df['data'].value_counts()

या रॉबर्ट मुइल द्वारा सुझाया गया यह अच्छा वन-लाइनर:

pd.Series([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]).value_counts()

4
बस एक नोट: DataFrame या numpy की जरूरत नहीं है, एक सूची से सीधे एक श्रृंखला में जा सकते हैं: pd.Series([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]).value_counts()
रॉबर्ट मुइल

बहुत बढ़िया, यह एक अच्छा एक-लाइनर है। बिग अप
शब्दफिर वाइज

8

कोई भी उपयोग करने के लिए सुझाव दिया numpy.bincount(input, minlength)साथ minlength = np.size(input), लेकिन यह एक अच्छा समाधान है, और निश्चित रूप से हो रहा है सबसे तेजी से :

In [1]: choices = np.random.randint(0, 100, 10000)

In [2]: %timeit [ np.sum(choices == k) for k in range(min(choices), max(choices)+1) ]
100 loops, best of 3: 2.67 ms per loop

In [3]: %timeit np.unique(choices, return_counts=True)
1000 loops, best of 3: 388 µs per loop

In [4]: %timeit np.bincount(choices, minlength=np.size(choices))
100000 loops, best of 3: 16.3 µs per loop

के बीच एक पागल गति है numpy.unique(x, return_counts=True)और numpy.bincount(x, minlength=np.max(x))!


यह हिस्टोग्राम की तुलना कैसे करता है?
जॉन ktejik

@johnktejik np.histogramएक ही चीज़ की गणना नहीं करता है। कोई बात नहीं तीन histogramफ़ंक्शन की तुलना में मैं फ़ंक्शन के साथ प्रस्ताव करता हूं , क्षमा करें।
नूरिन

1
@ N @reen bincountकेवल पूर्णांकों के लिए काम करता है, लेकिन यह ओपी की समस्या के लिए काम करता है, लेकिन शायद शीर्षक में वर्णित सामान्य समस्या के लिए नहीं। इसके अलावा क्या आपने bincountबहुत बड़े किलों के साथ सरणियों का उपयोग करने की कोशिश की है ?
शाही रात

@ImperishableNight नहीं, मैंने बड़े-बड़े किलों के साथ कोशिश नहीं की है, लेकिन किसी का भी ऐसा करने के लिए स्वागत है और अपने स्वयं के बेंचमार्क पोस्ट करें :-)
Nmarkreen

इस अल्पविकसित चाल के लिए धन्यवाद! मेरी मशीन bincountकी तुलना में लगभग चार गुना तेज है unique
ब्योर्न लिंडकविस्ट


6

y.tolist().count(val)

वैल 0 या 1 के साथ

चूंकि अजगर सूची में एक देशी फ़ंक्शन होता है count, इसलिए उस फ़ंक्शन का उपयोग करने से पहले सूची में कनवर्ट करना एक सरल समाधान है।


5

फिर भी एक और सरल समाधान numpy.count_nonzero () का उपयोग किया जा सकता है :

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
y_nonzero_num = np.count_nonzero(y==1)
y_zero_num = np.count_nonzero(y==0)
y_nonzero_num
4
y_zero_num
8

नाम को आपको गुमराह न करें, अगर आप इसे उदाहरण के रूप में बूलियन के साथ उपयोग करते हैं, तो यह चाल चलेगा।


5

घटनाओं की संख्या की गणना करने के लिए, आप निम्न का उपयोग कर सकते हैं np.unique(array, return_counts=True):

In [75]: boo = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

# use bool value `True` or equivalently `1`
In [77]: uniq, cnts = np.unique(boo, return_counts=1)
In [81]: uniq
Out[81]: array([0, 1])   #unique elements in input array are: 0, 1

In [82]: cnts
Out[82]: array([8, 4])   # 0 occurs 8 times, 1 occurs 4 times

4

मैं np.where का उपयोग करूंगा:

how_many_0 = len(np.where(a==0.)[0])
how_many_1 = len(np.where(a==1.)[0])


2

एक सामान्य और सरल उत्तर होगा:

numpy.sum(MyArray==x)   # sum of a binary list of the occurence of x (=0 or 1) in MyArray

जो इस पूर्ण कोड में छूट के रूप में परिणाम होगा

import numpy
MyArray=numpy.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])  # array we want to search in
x=0   # the value I want to count (can be iterator, in a list, etc.)
numpy.sum(MyArray==0)   # sum of a binary list of the occurence of x in MyArray

अब यदि MyArray कई आयामों में है और आप लाइन में मानों के वितरण की घटना को गिनना चाहते हैं (= इसके बाद पैटर्न)

MyArray=numpy.array([[6, 1],[4, 5],[0, 7],[5, 1],[2, 5],[1, 2],[3, 2],[0, 2],[2, 5],[5, 1],[3, 0]])
x=numpy.array([5,1])   # the value I want to count (can be iterator, in a list, etc.)
temp = numpy.ascontiguousarray(MyArray).view(numpy.dtype((numpy.void, MyArray.dtype.itemsize * MyArray.shape[1])))  # convert the 2d-array into an array of analyzable patterns
xt=numpy.ascontiguousarray(x).view(numpy.dtype((numpy.void, x.dtype.itemsize * x.shape[0])))  # convert what you search into one analyzable pattern
numpy.sum(temp==xt)  # count of the searched pattern in the list of patterns

2

एक स्वच्छ एक-लाइनर बनाने के लिए आप शब्दकोश समझ का उपयोग कर सकते हैं। शब्दकोश समझ के बारे में और अधिक जानकारी यहाँ मिल सकती है

>>>counts = {int(value): list(y).count(value) for value in set(y)}
>>>print(counts)
{0: 8, 1: 4}

यह आपके ndarray में कुंजियों के रूप में मानों के साथ एक शब्दकोश बनाएगा, और क्रमशः कुंजियों के मूल्यों के रूप में मानों की गणना करेगा।

जब भी आप इस प्रारूप की सरणियों में किसी मूल्य की घटनाओं को गिनना चाहते हैं तो यह काम करेगा।


2

इसे इस्तेमाल करे:

a = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
list(a).count(1)

1

यह निम्न विधि में आसानी से किया जा सकता है

y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
y.tolist().count(1)

1

चूँकि आपके ndarray में केवल 0 और 1 होते हैं, आप 0s की घटना को प्राप्त करने के लिए 1s और len () - sum () की घटना को प्राप्त करने के लिए sum () का उपयोग कर सकते हैं।

num_of_ones = sum(array)
num_of_zeros = len(array)-sum(array)

1

आपके पास यहां केवल 1 और 0 के साथ एक विशेष सरणी है। तो एक ट्रिक है इस्तेमाल करने की

np.mean(x)

जो आपके सरणी में आपको 1s का प्रतिशत देता है। वैकल्पिक रूप से, उपयोग करें

np.sum(x)
np.sum(1-x)

आप अपने सरणी में 1 और 0 की पूर्ण संख्या देंगे।


1
dict(zip(*numpy.unique(y, return_counts=True)))

बस यहां से सेपो एनारवी की टिप्पणी की नकल की गई जो उचित उत्तर देने के योग्य है


0

इसमें एक और कदम शामिल है, लेकिन एक अधिक लचीला समाधान जो 2d सरणियों के लिए भी काम करेगा और अधिक जटिल फिल्टर एक बूलियन मास्क बनाना है और फिर मास्क पर .sum () का उपयोग करना है।

>>>>y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>>>mask = y == 0
>>>>mask.sum()
8

0

यदि आप संख्यात्मक या संग्रह मॉड्यूल का उपयोग नहीं करना चाहते हैं, तो आप शब्दकोश का उपयोग कर सकते हैं:

d = dict()
a = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
for item in a:
    try:
        d[item]+=1
    except KeyError:
        d[item]=1

परिणाम:

>>>d
{0: 8, 1: 4}

बेशक आप एक if / else स्टेटमेंट का भी उपयोग कर सकते हैं। मुझे लगता है कि काउंटर फ़ंक्शन लगभग एक ही काम करता है लेकिन यह अधिक पारदर्शी है।


0

सामान्य प्रविष्टियों के लिए:

x = np.array([11, 2, 3, 5, 3, 2, 16, 10, 10, 3, 11, 4, 5, 16, 3, 11, 4])
n = {i:len([j for j in np.where(x==i)[0]]) for i in set(x)}
ix = {i:[j for j in np.where(x==i)[0]] for i in set(x)}

एक गिनती का उत्पादन करेगा:

{2: 2, 3: 4, 4: 2, 5: 2, 10: 2, 11: 3, 16: 2}

और सूचकांक:

{2: [1, 5],
3: [2, 4, 9, 14],
4: [11, 16],
5: [3, 12],
10: [7, 8],
11: [0, 10, 15],
16: [6, 13]}

0

यहां मेरे पास कुछ है, जिसके माध्यम से आप किसी विशेष संख्या की घटना की संख्या की गणना कर सकते हैं: अपने कोड के अनुसार

count_of_zero = सूची (y [y == 0])। गिनती (0)

प्रिंट (count_of_zero)

// मैच के अनुसार बूलियन मान होंगे और ट्रू वैल्यू के अनुसार नंबर 0 वापस होगा


0

यदि आप सबसे तेज़ निष्पादन में रुचि रखते हैं, तो आप पहले से जानते हैं कि किस मूल्य (ओं) को देखना है, और आपकी सरणी 1D है, या आप अन्यथा चपटा सरणी पर परिणाम में रुचि रखते हैं (जिस स्थिति में फ़ंक्शन का इनपुट होना चाहिए np.flatten(arr)सिर्फ रहने के बजाय arr), फिर नुम्बा आपका दोस्त है:

import numba as nb


@nb.jit
def count_nb(arr, value):
    result = 0
    for x in arr:
        if x == value:
            result += 1
    return result

या, बहुत बड़ी सरणियों के लिए जहां समानांतरकरण फायदेमंद हो सकता है:

@nb.jit(parallel=True)
def count_nbp(arr, value):
    result = 0
    for i in nb.prange(arr.size):
        if arr[i] == value:
            result += 1
    return result

इन के खिलाफ बेंचमार्किंग np.count_nonzero()(जिसमें एक अस्थायी सरणी बनाने की समस्या भी है जिसे टाला जा सकता है) और np.unique()आधारित समाधान

import numpy as np


def count_np(arr, value):
    return np.count_nonzero(arr == value)
import numpy as np


def count_np2(arr, value):
    uniques, counts = np.unique(a, return_counts=True)
    counter = dict(zip(uniques, counts))
    return counter[value] if value in counter else 0 

के साथ उत्पन्न इनपुट के लिए:

def gen_input(n, a=0, b=100):
    return np.random.randint(a, b, n)

निम्नलिखित भूखंड प्राप्त किए जाते हैं (भूखंडों की दूसरी पंक्ति तेजी से दृष्टिकोण पर एक ज़ूम है):

bm_full bm_zoom

यह दिखाते हुए कि नुंबा-आधारित समाधान न्यूमपाइ काउंटरपार्ट्स की तुलना में काफी तेज है, और, बहुत बड़े इनपुट के लिए, समानांतर दृष्टिकोण भोले की तुलना में तेज है।


पूर्ण कोड यहां उपलब्ध है


0

यदि आप जनरेटर का उपयोग करके बहुत बड़ी सरणियों के साथ काम कर रहे हैं तो एक विकल्प हो सकता है। यहाँ अच्छी बात यह है कि यह दृष्टिकोण दोनों सरणियों और सूचियों के लिए ठीक काम करता है और आपको किसी अतिरिक्त पैकेज की आवश्यकता नहीं है। इसके अतिरिक्त, आप उस मेमोरी का उपयोग नहीं कर रहे हैं।

my_array = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
sum(1 for val in my_array if val==0)
Out: 8

-1

Numpy के पास इसके लिए एक मॉड्यूल है। बस एक छोटी सी हैक। डिब्बे के रूप में अपने इनपुट सरणी रखो।

numpy.histogram(y, bins=y)

आउटपुट 2 सरणियाँ हैं। मूल्यों के साथ एक, अन्य इसी आवृत्तियों के साथ।


क्या 'डिब्बे' को एक संख्या नहीं माना जाता है?
जॉन ktejik

1
हाँ @ जोंकट्जीक आप सही कह रहे हैं। यह उत्तर काम नहीं करता है।
नूरिन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.