मान लीजिए कि मेरे पास अजगर में निम्नलिखित सूची है:
a = [1,2,3,1,2,1,1,1,3,2,2,1]
इस सूची में सबसे स्वच्छ तरीके से सबसे अधिक संख्या कैसे प्राप्त करें?
मान लीजिए कि मेरे पास अजगर में निम्नलिखित सूची है:
a = [1,2,3,1,2,1,1,1,3,2,2,1]
इस सूची में सबसे स्वच्छ तरीके से सबसे अधिक संख्या कैसे प्राप्त करें?
जवाबों:
यदि आपकी सूची में सभी गैर-नकारात्मक स्याही हैं, तो आपको numpy.bincounts पर एक नज़र डालनी चाहिए:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html
और फिर शायद np.argmax का उपयोग करें:
a = np.array([1,2,3,1,2,1,1,1,3,2,2,1])
counts = np.bincount(a)
print(np.argmax(counts))
अधिक जटिल सूची के लिए (जिसमें संभवत: नकारात्मक संख्या या गैर-पूर्णांक मान शामिल हैं), आप np.histogram
एक समान तरीके से उपयोग कर सकते हैं । वैकल्पिक रूप से, यदि आप केवल सुन्नता का उपयोग किए बिना अजगर में काम करना चाहते हैं, तो collections.Counter
इस तरह के डेटा को संभालने का एक अच्छा तरीका है।
from collections import Counter
a = [1,2,3,1,2,1,1,1,3,2,2,1]
b = Counter(a)
print(b.most_common(1))
scipy.stats.mode
, हालांकि कम सामान्य है।
Counter(array).most_common(1)[0][0]
तुम उपयोग कर सकते हो
(values,counts) = np.unique(a,return_counts=True)
ind=np.argmax(counts)
print values[ind] # prints the most frequent element
यदि कुछ तत्व एक दूसरे के रूप में लगातार होता है, तो यह कोड केवल पहला तत्व वापस करेगा।
values[counts.argmax()]
तो पहला मान वापस आएगा। उन सभी को प्राप्त करने के लिए, हम उपयोग कर सकते हैं values[counts == counts.max()]
।
>>> # small array
>>> a = [12,3,65,33,12,3,123,888000]
>>>
>>> import collections
>>> collections.Counter(a).most_common()[0][0]
3
>>> %timeit collections.Counter(a).most_common()[0][0]
100000 loops, best of 3: 11.3 µs per loop
>>>
>>> import numpy
>>> numpy.bincount(a).argmax()
3
>>> %timeit numpy.bincount(a).argmax()
100 loops, best of 3: 2.84 ms per loop
>>>
>>> import scipy.stats
>>> scipy.stats.mode(a)[0][0]
3.0
>>> %timeit scipy.stats.mode(a)[0][0]
10000 loops, best of 3: 172 µs per loop
>>>
>>> from collections import defaultdict
>>> def jjc(l):
... d = defaultdict(int)
... for i in a:
... d[i] += 1
... return sorted(d.iteritems(), key=lambda x: x[1], reverse=True)[0]
...
>>> jjc(a)[0]
3
>>> %timeit jjc(a)[0]
100000 loops, best of 3: 5.58 µs per loop
>>>
>>> max(map(lambda val: (a.count(val), val), set(a)))[1]
12
>>> %timeit max(map(lambda val: (a.count(val), val), set(a)))[1]
100000 loops, best of 3: 4.11 µs per loop
>>>
समस्या जैसी छोटी सरणियों के लिए 'सेट' के साथ 'अधिकतम' है।
@ डेविड सैंडर्स के अनुसार, यदि आप सरणी का आकार 100,000 तत्वों की तरह बढ़ाते हैं, तो "अधिकतम w / सेट" एल्गोरिथ्म दूर तक सबसे खराब होता है जबकि "सुन्न bincount" विधि सबसे अच्छा है।
a = (np.random.rand(100000) * 1000).round().astype('int'); a_list = list(a)
) तक बढ़ाते हैं , तो आपका "अधिकतम w / सेट" एल्गोरिथ्म दूर तक सबसे खराब होता है जबकि "सुन्न bincount" विधि सबसे अच्छा है। मैंने a_list
मूल अजगर कोड के लिए और a
खस्ता कोड से बचने के लिए इस परीक्षण का उपयोग किया , ताकि परिणामों को खराब करने वाले मार्शलों से बचा जा सके।
यदि आप किसी भी मॉड्यूल को लोड किए बिना सबसे अधिक मूल्य (सकारात्मक या नकारात्मक) प्राप्त करना चाहते हैं, तो आप निम्नलिखित कोड का उपयोग कर सकते हैं:
lVals = [1,2,3,1,2,1,1,1,3,2,2,1]
print max(map(lambda val: (lVals.count(val), val), set(lVals)))
max(set(lVals), key=lVals.count)
, जो lVals
लगभग O (n ^ 2) (संभालने वाले O (n) अद्वितीय के प्रत्येक अद्वितीय तत्व के लिए एक O (n) गणना करता है तत्व)। जोश एडेल द्वारा सुझाए गएcollections.Counter(lVals).most_common(1)[0][0]
मानक पुस्तकालय से उपयोग करना केवल ओ (एन) है।
जबकि ऊपर दिए गए अधिकांश उत्तर आपके लिए उपयोगी हैं, यदि आप: 1) को गैर-सकारात्मक-पूर्णांक मानों (जैसे फ़्लोट्स या नकारात्मक पूर्णांक ;-)) का समर्थन करने की आवश्यकता है, और पायथन 2.7 (जो संग्रह में उपलब्ध नहीं हैं) आवश्यकता होती है), और 3) अपने कोड में scipy (या यहां तक कि सुन्न) की निर्भरता को जोड़ने के लिए नहीं पसंद करते हैं, तो एक शुद्ध रूप से अजगर 2.6 समाधान है कि हे (nlogn) (यानी, कुशल) सिर्फ यह है:
from collections import defaultdict
a = [1,2,3,1,2,1,1,1,3,2,2,1]
d = defaultdict(int)
for i in a:
d[i] += 1
most_frequent = sorted(d.iteritems(), key=lambda x: x[1], reverse=True)[0]
इस पद्धति पर विस्तार करते हुए , डेटा के मोड को खोजने के लिए आवेदन किया जाता है, जहां आपको वितरण के केंद्र से मूल्य कितनी दूर है यह देखने के लिए वास्तविक सरणी के सूचकांक की आवश्यकता हो सकती है।
(_, idx, counts) = np.unique(a, return_index=True, return_counts=True)
index = idx[np.argmax(counts)]
mode = a[index]
जब len (np.argmax (मायने रखता है))> 1 मोड को त्यागना याद रखें
पायथन 3 में निम्नलिखित कार्य करना चाहिए:
max(set(a), key=lambda x: a.count(x))
में शुरू Python 3.4
, मानक पुस्तकालय में statistics.mode
एकल सबसे सामान्य डेटा बिंदु वापस करने के लिए फ़ंक्शन शामिल है ।
from statistics import mode
mode([1, 2, 3, 1, 2, 1, 1, 1, 3, 2, 2, 1])
# 1
यदि एक ही आवृत्ति के साथ कई मोड हैं, statistics.mode
तो पहले वाला सामना करना पड़ता है।
आरंभ करते हुए Python 3.8
, statistics.multimode
फ़ंक्शन उस क्रम में सबसे अधिक बार होने वाले मूल्यों की सूची देता है जिस क्रम में वे पहली बार सामने आए थे:
from statistics import multimode
multimode([1, 2, 3, 1, 2])
# [1, 2]
यहां एक सामान्य समाधान है जिसे अक्ष के साथ लागू किया जा सकता है, मूल्यों की परवाह किए बिना, विशुद्ध रूप से सुन्न का उपयोग करके। मैंने यह भी पाया है कि यह scipy.stats.mode की तुलना में बहुत तेज़ है अगर बहुत सारे अनूठे मूल्य हैं।
import numpy
def mode(ndarray, axis=0):
# Check inputs
ndarray = numpy.asarray(ndarray)
ndim = ndarray.ndim
if ndarray.size == 1:
return (ndarray[0], 1)
elif ndarray.size == 0:
raise Exception('Cannot compute mode on empty array')
try:
axis = range(ndarray.ndim)[axis]
except:
raise Exception('Axis "{}" incompatible with the {}-dimension array'.format(axis, ndim))
# If array is 1-D and numpy version is > 1.9 numpy.unique will suffice
if all([ndim == 1,
int(numpy.__version__.split('.')[0]) >= 1,
int(numpy.__version__.split('.')[1]) >= 9]):
modals, counts = numpy.unique(ndarray, return_counts=True)
index = numpy.argmax(counts)
return modals[index], counts[index]
# Sort array
sort = numpy.sort(ndarray, axis=axis)
# Create array to transpose along the axis and get padding shape
transpose = numpy.roll(numpy.arange(ndim)[::-1], axis)
shape = list(sort.shape)
shape[axis] = 1
# Create a boolean array along strides of unique values
strides = numpy.concatenate([numpy.zeros(shape=shape, dtype='bool'),
numpy.diff(sort, axis=axis) == 0,
numpy.zeros(shape=shape, dtype='bool')],
axis=axis).transpose(transpose).ravel()
# Count the stride lengths
counts = numpy.cumsum(strides)
counts[~strides] = numpy.concatenate([[0], numpy.diff(counts[~strides])])
counts[strides] = 0
# Get shape of padded counts and slice to return to the original shape
shape = numpy.array(sort.shape)
shape[axis] += 1
shape = shape[transpose]
slices = [slice(None)] * ndim
slices[axis] = slice(1, None)
# Reshape and compute final counts
counts = counts.reshape(shape).transpose(transpose)[slices] + 1
# Find maximum counts and return modals/counts
slices = [slice(None, i) for i in sort.shape]
del slices[axis]
index = numpy.ogrid[slices]
index.insert(axis, numpy.argmax(counts, axis=axis))
return sort[index], counts[index]
मैं हाल ही में एक परियोजना कर रहा हूं और संग्रह का उपयोग कर रहा हूं। मुठभेड़ (जो मुझे अत्याचार करता है)।
काउंटर इन कलेक्शन का मेरी राय में बहुत खराब प्रदर्शन है। यह सिर्फ तानाशाही को लपेटने वाला वर्ग है ()।
क्या बुरा है, यदि आप इसकी विधि को प्रोफाइल करने के लिए cProfile का उपयोग करते हैं, तो आपको पूरे समय को बर्बाद करते हुए बहुत सारे '__missing__' और '__instancecheck__' सामान देखने चाहिए।
इसका सबसे अधिक उपयोग करें सावधान रहें (), क्योंकि हर बार यह एक प्रकार का आह्वान करेगा जो इसे बेहद धीमा बनाता है। और यदि आप most_common (x) का उपयोग करते हैं, तो यह एक ढेर प्रकार का आह्वान करेगा, जो धीमा भी है।
Btw, numpy के बिंकाउंट में भी एक समस्या है: यदि आप np.bincount ([1,2,4000000]) का उपयोग करते हैं, तो आपको 4000000 तत्वों के साथ एक सरणी मिलेगी।
np.bincount([1, 2, 3, 1, 2, 1, 1, 1, 3, 2, 2, 1]).argmax()