হালনাগাদ
scipy.stats.mode
ফাংশন উল্লেখযোগ্যভাবে পোস্টটি যেহেতু অপ্টিমাইজ করা হয়েছে, এবং প্রস্তাবিত পদ্ধতি হবে
পুরানো উত্তর
এটি একটি জটিল সমস্যা, যেহেতু অক্ষ সহ মোড গণনা করার মতো খুব বেশি কিছু নেই। সমাধান 1-ডি অ্যারে, যেখানে জন্য সোজা এগিয়ে numpy.bincount
কুশলী হয়, সহ numpy.unique
সঙ্গে return_counts
যেমন ARG True
। আমি দেখতে পাই সবচেয়ে সাধারণ এন-ডাইমেনশনাল ফাংশনটি হ'ল স্কিপি.স্ট্যাটস.মোড, যদিও এটি নিষিদ্ধভাবে ধীর - বিশেষত অনেকগুলি অনন্য মান সহ বড় অ্যারেগুলির জন্য। সমাধান হিসাবে, আমি এই ফাংশনটি বিকাশ করেছি এবং এটি ব্যবহার করে প্রচুর পরিমাণে:
import numpy
def mode(ndarray, axis=0):
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 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 = numpy.sort(ndarray, axis=axis)
transpose = numpy.roll(numpy.arange(ndim)[::-1], axis)
shape = list(sort.shape)
shape[axis] = 1
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()
counts = numpy.cumsum(strides)
counts[~strides] = numpy.concatenate([[0], numpy.diff(counts[~strides])])
counts[strides] = 0
shape = numpy.array(sort.shape)
shape[axis] += 1
shape = shape[transpose]
slices = [slice(None)] * ndim
slices[axis] = slice(1, None)
counts = counts.reshape(shape).transpose(transpose)[slices] + 1
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]
ফলাফল:
In [2]: a = numpy.array([[1, 3, 4, 2, 2, 7],
[5, 2, 2, 1, 4, 1],
[3, 3, 2, 2, 1, 1]])
In [3]: mode(a)
Out[3]: (array([1, 3, 2, 2, 1, 1]), array([1, 2, 2, 2, 1, 2]))
কিছু মানদণ্ড:
In [4]: import scipy.stats
In [5]: a = numpy.random.randint(1,10,(1000,1000))
In [6]: %timeit scipy.stats.mode(a)
10 loops, best of 3: 41.6 ms per loop
In [7]: %timeit mode(a)
10 loops, best of 3: 46.7 ms per loop
In [8]: a = numpy.random.randint(1,500,(1000,1000))
In [9]: %timeit scipy.stats.mode(a)
1 loops, best of 3: 1.01 s per loop
In [10]: %timeit mode(a)
10 loops, best of 3: 80 ms per loop
In [11]: a = numpy.random.random((200,200))
In [12]: %timeit scipy.stats.mode(a)
1 loops, best of 3: 3.26 s per loop
In [13]: %timeit mode(a)
1000 loops, best of 3: 1.75 ms per loop
সম্পাদনা: একটি পটভূমির অনেক বেশি সরবরাহ করা হয়েছে এবং আরও মেমরি-দক্ষ হওয়ার জন্য পদ্ধতির পরিবর্তন করা হয়েছে