একটি ন্যালি ভেক্টরে সর্বাধিক ঘন সংখ্যাটি সন্ধান করুন


123

ধরুন পাইথনে আমার নীচের তালিকা রয়েছে:

a = [1,2,3,1,2,1,1,1,3,2,2,1]

ঝরঝরেভাবে এই তালিকার সর্বাধিক ঘন সংখ্যাটি কীভাবে খুঁজে পাবেন?

উত্তর:


193

যদি আপনার তালিকায় সমস্ত অ-নেতিবাচক অন্তর অন্তর্ভুক্ত থাকে তবে আপনাকে numpy.bincounts একবার দেখে নেওয়া উচিত:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html

এবং তারপরে সম্ভবত এনপি.আরগম্যাক্স ব্যবহার করুন:

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)

58
+1 টি। স্রেফ হতে পারেnp.bincount([1, 2, 3, 1, 2, 1, 1, 1, 3, 2, 2, 1]).argmax()
নিকোলাই ফেটিসসোভ

1
+1 টি। এটি কমপক্ষে scipy.stats.modeসাধারণ হলেও এর চেয়ে কমপক্ষে দ্রুততার একটি ক্রম ।
ফ্রেড ফু

চমৎকার উত্তর! যাইহোক, যদি কেউ অজগর ২.6 এ থাকে তবে সংগ্রহসমূহ oun কাউন্টার পাওয়া যায় না। সেক্ষেত্রে নীচে আমার উত্তরটি দেখুন।
জেজেসি

19
২০১ 2016-এর পরে আমাদের মধ্যে যারা ঘুরেছেন তাদের কাছে: আমি এই উত্তরটি অপছন্দ করি, কারণ বিঙ্কাউন্ট (আর্ট) অ্যারের বৃহত্তম উপাদান হিসাবে বড় হিসাবে একটি অ্যারের প্রদান করে, তাই একটি বিশাল পরিসর সহ একটি ছোট অ্যারে অতিরিক্ত মাত্রায় বড় অ্যারে তৈরি করবে। নীচে অ্যাপোইংটাসের উত্তরটি আরও ভাল, যদিও আমি মনে করি না যে এই উত্তরটি তৈরি করা হয়েছিল, 2011 সালে numpy.unique () এর অস্তিত্ব ছিল।
ওয়েহার্ডো

2
পাইথন 3 :Counter(array).most_common(1)[0][0]
ডায়রালিক

80

আপনি ব্যবহার করতে পারেন

(values,counts) = np.unique(a,return_counts=True)
ind=np.argmax(counts)
print values[ind]  # prints the most frequent element

যদি কিছু উপাদান অন্য একটি হিসাবে ঘন ঘন হয়, এই কোডটি কেবলমাত্র প্রথম উপাদানটি ফেরত দেবে।


4
আমি এটিকে সবচেয়ে সহায়ক বলে মনে করি কারণ এটি জেনেরিক, সংক্ষিপ্ত এবং কিছু উত্পন্ন সূচক দ্বারা মান বা গণনা থেকে উপাদানগুলি টানতে দেয়।
ryanjdillon

2
আমাদের যদি একাধিক ঘন ঘন মান থাকে values[counts.argmax()]তবে প্রথম মানটি ফিরিয়ে দেবে। তাদের সব পেতে, আমরা ব্যবহার করতে পারি values[counts == counts.max()]
ডাব্লু ঝু

44

আপনি যদি সায়পি ব্যবহার করতে ইচ্ছুক হন :

>>> from scipy.stats import mode
>>> mode([1,2,3,1,2,1,1,1,3,2,2,1])
(array([ 1.]), array([ 6.]))
>>> most_frequent = mode([1,2,3,1,2,1,1,1,3,2,2,1])[0][0]
>>> most_frequent
1.0

30

এখানে কিছু সমাধানের জন্য পারফরম্যান্স (আইপিথন ব্যবহার করে):

>>> # 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
>>> 

সমস্যার মতো ছোট অ্যারেগুলির জন্য 'সেট' সহ সেরা 'হ'ল ।

@ ডেভিড স্যান্ডার্সের মতে, আপনি যদি অ্যারের আকারটি ১০০,০০০ উপাদানের মতো বাড়িয়ে দেন তবে "সর্বাধিক ডাব্লু / সেট" অ্যালগরিদম শেষ পর্যন্ত সবচেয়ে খারাপ হিসাবে শেষ হয় যেখানে "নম্পি বিঙ্কাউন্ট" পদ্ধতিটি সেরা।


1
@ ইউলিয়াস কার্টকে একাধিক মামলার বিপরীতে পরীক্ষা করার জন্য আমাদের সেরা পদ্ধতির ইঙ্গিত করার জন্য: ছোট অ্যারে, বড় অ্যারে, এলোমেলো অ্যারে, রিয়েল ওয়ার্ল্ড অ্যারে ( টাইমসোর্ট যেমন বাছাইয়ের জন্য করা হয়), ... তবে আমি আপনার সাথে একমত
iuridiniz ২

3
আপনার পদ্ধতির মতো কেবল একটি ছোট অ্যারে ব্যবহার করা বিভিন্ন অ্যালগরিদমের মধ্যে খুব ভাল পার্থক্য করে না।
ডেভিড স্যান্ডার্স 21

10
আপনি যদি পরীক্ষার তালিকার আকার 100000 ( a = (np.random.rand(100000) * 1000).round().astype('int'); a_list = list(a)) এ বাড়িয়ে দেন তবে আপনার "সর্বাধিক ডাব্লু / সেট" অ্যালগরিদমটি এখন পর্যন্ত সবচেয়ে খারাপ হিসাবে শেষ হবে যখন "নম্পি বিনপাউন্ট" পদ্ধতিটি সেরা। আমি ফলাফলটি স্ক্রাইংয়ের ব্যয়কে মার্শালিং এড়াতে a_listনেটিভ পাইথন কোড এবং aনম্পি কোডের জন্য ব্যবহার করে এই পরীক্ষাটি চালিয়েছি।
ডেভিড স্যান্ডার্স

4

এছাড়াও আপনি যদি কোনও মডিউল লোড না করে সর্বাধিক ঘন মান (ধনাত্মক বা নেতিবাচক) পেতে চান তবে নীচের কোডটি ব্যবহার করতে পারেন:

lVals = [1,2,3,1,2,1,1,1,3,2,2,1]
print max(map(lambda val: (lVals.count(val), val), set(lVals)))

1
এটি কিছুকাল আগে থেকে, তবে উত্তরোত্তর জন্য: এটি সহজেই পঠনযোগ্য সমান max(set(lVals), key=lVals.count), যা lValsপ্রায় O (n ^ 2) (ও (এন) কে অনন্য বলে ধরে নিয়ে প্রতিটি অনন্য উপাদানের জন্য একটি O (n) গণনা করে ) উপাদান)। ব্যবহার collections.Counter(lVals).most_common(1)[0][0], যেমন মান লাইব্রেরি থেকে JoshAdel দ্বারা প্রস্তাবিত শুধুমাত্র O (ঢ) হয়।
ডগল

3

যদিও উপরের উত্তরগুলির বেশিরভাগটি দরকারী, যদি আপনার ক্ষেত্রে: ১) অ-ধনাত্মক-পূর্ণসংখ্যার মানগুলি সমর্থন করা প্রয়োজন (যেমন ফ্লোটস বা নেতিবাচক পূর্ণসংখ্যা ;-)) এবং ২) পাইথন ২.7 এ নেই (যা সংগ্রহ.সূত্র) প্রয়োজন), এবং 3) আপনার কোডে স্কিপি (বা এমনকি ছদ্মবেশী) এর নির্ভরতা যুক্ত না করা পছন্দ করে, তবে ও (নলগন) (অর্থাত্ দক্ষ) হ'ল বিশুদ্ধ পাইথন ২.6 সমাধানটি কেবল এটি:

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]

2

আমি জোশএডেলের সমাধানটি পছন্দ করি।

তবে একটি মাত্র ক্যাচ আছে।

np.bincount()সমাধান শুধুমাত্র সংখ্যা উপর কাজ করে।

আপনার যদি স্ট্রিং থাকে তবে collections.Counterসমাধান আপনার পক্ষে কাজ করবে।


1

এই পদ্ধতিটি প্রসারণ করে ডেটা মোডটি অনুসন্ধানের জন্য প্রয়োগ করা হয়েছে যেখানে বিতরণের কেন্দ্র থেকে মানটি কতটা দূরে রয়েছে তা দেখতে আপনার প্রকৃত অ্যারের সূচকের প্রয়োজন হতে পারে।

(_, idx, counts) = np.unique(a, return_index=True, return_counts=True)
index = idx[np.argmax(counts)]
mode = a[index]

লেন (np.argmax (গণনা))> 1 এ মোডটি বাতিল করতে ভুলবেন না



1

শুরু করে 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]

0

এখানে একটি সাধারণ সমাধান যা নিখুঁতভাবে নির্লজ্জ ব্যবহার করে মান নির্বিশেষে অক্ষের সাথে প্রয়োগ করা যেতে পারে। আমি আরও খুঁজে পেয়েছি যে স্কিপি.স্ট্যাটস.মোডের তুলনায় এটি আরও দ্রুত if

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]

-1

আমি সম্প্রতি একটি প্রকল্প করছি এবং সংগ্রহগুলি ব্যবহার করছি oun কাউন্টার ((যা আমাকে নির্যাতন করেছে)।

সংগ্রহে থাকা কাউন্টারে আমার মতে খুব খারাপ অভিনয় রয়েছে। এটি কেবল একটি শ্রেণি মোড়ানোর আদেশ ()।

সবচেয়ে খারাপ বিষয়, আপনি যদি সিপ্রোফিলটিকে এর পদ্ধতিটি প্রোফাইল করতে ব্যবহার করেন তবে আপনার পুরো সময় নষ্ট করা অনেক '__ মিসিং__' এবং '__instancecheck__' স্টাফ দেখতে হবে।

এর Most_common () ব্যবহার করে সাবধান থাকুন, কারণ প্রতিবার এটি এমন ধরণের সাড়া দেয় যা এটি অত্যন্ত ধীর করে তোলে। এবং যদি আপনি সর্বাধিক_কমোন (এক্স) ব্যবহার করেন তবে এটি একটি হিপ বাছাই শুরু করবে, এটিও ধীর is

বিটিডব্লিউ, নম্পির বিন্দাউন্টেও একটি সমস্যা রয়েছে: আপনি যদি এনপি.বিঙ্কাউন্ট ([1,2,4000000]) ব্যবহার করেন তবে 4000000 উপাদান সহ আপনি একটি অ্যারে পাবেন।


3
একটি ডিকটি পাইথনের সর্বাধিক সূক্ষ্ম-সুরযুক্ত ডেটা কাঠামো এবং যথেচ্ছ বিষয়গুলি গণনা করার জন্য আদর্শ। বিপরীতে, বিনিং শুধুমাত্র সংখ্যার মানগুলিতে কাজ করে এবং আপনাকে ঘনিষ্ঠ ব্যবধানে পৃথক পৃথক মানগুলির মধ্যে অ্যালিজিং প্রতিরোধ করতে দেয় না। কাউন্টারের ক্ষেত্রে, __missing__ পদ্ধতিটি তখনই বলা হয় যখন কোনও উপাদানটি প্রথম দেখা যায়; অন্যথায়, এর উপস্থিতি ব্যয়বহুল। দ্রষ্টব্য, বেশিরভাগ ক্ষেত্রেই মোস্ট_কমন () পদ্ধতিটি নির্লজ্জভাবে দ্রুত হয় কারণ মোট ডেটাসেটের তুলনায় গাদাটি খুব ছোট। বেশিরভাগ ক্ষেত্রে, সর্বাধিক_কমন () পদ্ধতিটি কমপক্ষে () এর চেয়ে কিছুটা বেশি তুলনা করে ।
রায়মন্ড হেটেঞ্জার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.