Mam tablicę 2D zawierającą liczby całkowite (zarówno dodatnie, jak i ujemne). Każdy wiersz przedstawia wartości w czasie dla określonego miejsca przestrzennego, podczas gdy każda kolumna przedstawia wartości dla różnych miejsc przestrzennych w danym czasie.
Więc jeśli tablica wygląda następująco:
1 3 4 2 2 7
5 2 2 1 4 1
3 3 2 2 1 1
Wynik powinien być
1 3 2 2 2 1
Zwróć uwagę, że gdy istnieje wiele wartości trybu, dowolna (wybrana losowo) może zostać ustawiona jako tryb.
Mogę iterować tryb wyszukiwania kolumn pojedynczo, ale miałem nadzieję, że numpy może mieć wbudowaną funkcję do tego. Lub jeśli istnieje sztuczka, aby znaleźć to skutecznie bez zapętlania.
Odpowiedzi:
Sprawdź
scipy.stats.mode()
(inspirowane komentarzem @ tom10):import numpy as np from scipy import stats a = np.array([[1, 3, 4, 2, 2, 7], [5, 2, 2, 1, 4, 1], [3, 3, 2, 2, 1, 1]]) m = stats.mode(a) print(m)
Wynik:
ModeResult(mode=array([[1, 3, 2, 2, 1, 1]]), count=array([[1, 2, 2, 2, 1, 2]]))
Jak widać, zwraca zarówno tryb, jak i liczby. Możesz wybrać tryby bezpośrednio poprzez
m[0]
:print(m[0])
Wynik:
[[1 3 2 2 1 1]]
źródło
import scipy.stats
wyraźnie zaznaczyć, nie jest to uwzględniane, gdy po prostu wykonujesz plikimport scipy
.axis=0
. Powyższy kod raportuje tryb w każdej kolumnie wejścia. Licznik mówi nam, ile razy widział raportowany tryb w każdej z kolumn. Jeśli chcesz tryb ogólny, musisz określićaxis=None
. Więcej informacji można znaleźć pod adresem docs.scipy.org/doc/scipy/reference/generated/ ...Aktualizacja
scipy.stats.mode
Funkcja została znacznie zoptymalizowany od tego postu, a byłoby to zalecana metodaStara odpowiedź
Jest to trudny problem, ponieważ nie ma zbyt wiele do obliczenia trybu wzdłuż osi. Rozwiązanie to jest proste dla tablic 1-D, w których
numpy.bincount
jest przydatny, a takżenumpy.unique
zreturn_counts
argTrue
. Najczęstszą funkcją n-wymiarową, jaką widzę, jest scipy.stats.mode, chociaż jest ona zbyt wolna - szczególnie w przypadku dużych tablic z wieloma unikalnymi wartościami. Jako rozwiązanie opracowałem tę funkcję i intensywnie z niej korzystam: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]
Wynik:
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]))
Niektóre testy porównawcze:
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
EDYCJA: Zapewniono więcej tła i zmodyfikowano podejście, aby zwiększyć wydajność pamięci
źródło
Rozwinięcie tej metody , zastosowane do znalezienia trybu danych, w którym może być potrzebny indeks rzeczywistej tablicy, aby zobaczyć, jak daleko wartość znajduje się od środka rozkładu.
(_, idx, counts) = np.unique(a, return_index=True, return_counts=True) index = idx[np.argmax(counts)] mode = a[index]
Pamiętaj, aby odrzucić tryb, gdy len (np.argmax (counts))> 1, również w celu sprawdzenia, czy jest on rzeczywiście reprezentatywny dla centralnego rozkładu Twoich danych, możesz sprawdzić, czy mieści się on w Twoim przedziale odchylenia standardowego.
źródło
Zgrabne rozwiązanie, które wykorzystuje tylko
numpy
(niescipy
aniCounter
klasę):A = np.array([[1,3,4,2,2,7], [5,2,2,1,4,1], [3,3,2,2,1,1]]) np.apply_along_axis(lambda x: np.bincount(x).argmax(), axis=0, arr=A)
źródło
scipy.stats.mode
. Gdy istnieje wiele wartości, które mają najwięcej występowania (wiele trybów), wyrzuci to oczekiwanie. Ale ta metoda automatycznie przyjmie „tryb pierwszy”.Jeśli chcesz używać tylko numpy:
x = [-1, 2, 1, 3, 3] vals,counts = np.unique(x, return_counts=True)
daje
(array([-1, 1, 2, 3]), array([1, 1, 1, 2]))
I wyodrębnij:
index = np.argmax(counts) return vals[index]
źródło
Myślę, że bardzo prostym sposobem byłoby użycie klasy Counter. Następnie możesz użyć funkcji most_common () instancji Counter, jak wspomniano tutaj .
W przypadku macierzy 1-w:
import numpy as np from collections import Counter nparr = np.arange(10) nparr[2] = 6 nparr[3] = 6 #6 is now the mode mode = Counter(nparr).most_common(1) # mode will be [(6,3)] to give the count of the most occurring value, so -> print(mode[0][0])
W przypadku tablic wielowymiarowych (niewielka różnica):
import numpy as np from collections import Counter nparr = np.arange(10) nparr[2] = 6 nparr[3] = 6 nparr = nparr.reshape((10,2,5)) #same thing but we add this to reshape into ndarray mode = Counter(nparr.flatten()).most_common(1) # just use .flatten() method # mode will be [(6,3)] to give the count of the most occurring value, so -> print(mode[0][0])
Może to być skuteczna implementacja lub nie, ale jest wygodna.
źródło
from collections import Counter n = int(input()) data = sorted([int(i) for i in input().split()]) sorted(sorted(Counter(data).items()), key = lambda x: x[1], reverse = True)[0][0] print(Mean)
Counter(data)
Liczy się częstotliwość i zwraca defaultdict.sorted(Counter(data).items())
sortuje za pomocą klawiszy, a nie częstotliwości. Na koniec należy posortować częstotliwość przy użyciu innej posortowanej zkey = lambda x: x[1]
. Odwrotna sytuacja mówi Pythonowi, aby sortował częstotliwość od największej do najmniejszej.źródło
najprostszy sposób w Pythonie, aby uzyskać tryb listy lub tablicy a
import statistics print("mode = "+str(statistics.(mode(a)))
Otóż to
źródło