Suponha que eu tenha a seguinte lista em python:
a = [1,2,3,1,2,1,1,1,3,2,2,1]
Como encontrar o número mais frequente nesta lista de maneira organizada?
python
numpy
statistics
Na hora certa
fonte
fonte
np.bincount([1, 2, 3, 1, 2, 1, 1, 1, 3, 2, 2, 1]).argmax()
scipy.stats.mode
, embora menos geral.Counter(array).most_common(1)[0][0]
Você pode usar
Se algum elemento for tão frequente quanto outro, esse código retornará apenas o primeiro elemento.
fonte
values[counts.argmax()]
retornará o primeiro valor. Para obter todos eles, podemos usarvalues[counts == counts.max()]
.Se você estiver disposto a usar o SciPy :
fonte
Apresentações (usando o iPython) para algumas soluções encontradas aqui:
Melhor é 'max' com 'set' para pequenas matrizes como o problema.
De acordo com @David Sanders, se você aumentar o tamanho da matriz para algo como 100.000 elementos, o algoritmo "max w / set" acaba sendo o pior de longe, enquanto o método "numpy bincount" é o melhor.
fonte
a = (np.random.rand(100000) * 1000).round().astype('int'); a_list = list(a)
), o algoritmo "max w / set" acaba sendo o pior de longe, enquanto o método "numpy bincount" é o melhor. Realizei esse teste usando oa_list
código python nativo e oa
código numpy para evitar custos de organização dos resultados.Além disso, se você deseja obter o valor mais frequente (positivo ou negativo) sem carregar nenhum módulo, pode usar o seguinte código:
fonte
max(set(lVals), key=lVals.count)
, que conta O (n) para cada elemento único delVals
aproximadamente O (n ^ 2) (assumindo O (n) exclusivo elementos). O usocollections.Counter(lVals).most_common(1)[0][0]
da biblioteca padrão, conforme sugerido por JoshAdel , é apenas O (n).Embora a maioria das respostas acima seja útil, no caso de você: 1) precisar dar suporte a valores inteiros não positivos (por exemplo, números flutuantes ou números negativos ;-)) e 2) não estão no Python 2.7 (que coleções. requer) e 3) prefere não adicionar a dependência de scipy (ou até mesmo numpy) ao seu código, então uma solução puramente python 2.6 que é O (nlogn) (ou seja, eficiente) é exatamente isso:
fonte
Eu gosto da solução de JoshAdel.
Mas há apenas uma captura.
A
np.bincount()
solução funciona apenas em números.Se você tiver seqüências de caracteres, a
collections.Counter
solução funcionará para você.fonte
Expandindo esse método , aplicado para encontrar o modo dos dados em que você pode precisar do índice da matriz real para ver a que distância o valor está do centro da distribuição.
Lembre-se de descartar o modo quando len (np.argmax (counts))> 1
fonte
No Python 3, o seguinte deve funcionar:
fonte
Começando
Python 3.4
, a biblioteca padrão inclui astatistics.mode
função para retornar o ponto de dados mais comum.Se houver vários modos com a mesma frequência,
statistics.mode
retornará o primeiro encontrado.Iniciando
Python 3.8
, astatistics.multimode
função retorna uma lista dos valores que ocorrem com mais frequência na ordem em que foram encontrados:fonte
Aqui está uma solução geral que pode ser aplicada ao longo de um eixo, independentemente dos valores, usando puramente numpy. Também descobri que isso é muito mais rápido que o scipy.stats.mode se houver muitos valores exclusivos.
fonte
Recentemente, estou fazendo um projeto e usando collections.Counter. (O que me torturou).
O contador nas coleções tem um desempenho muito, muito ruim, na minha opinião. É apenas um dict de quebra de classe ().
O que é pior: se você usar o cProfile para criar um perfil do método, verá muitas coisas '__missing__' e '__instancecheck__' desperdiçando o tempo todo.
Tenha cuidado ao usar o most_common (), porque toda vez ele invocaria uma classificação que a torna extremamente lenta. e se você usar most_common (x), ele chamará uma classificação de heap, que também é lenta.
Aliás, a conta do numpy também tem um problema: se você usar np.bincount ([1,2,4000000]), obterá uma matriz com 4000000 elementos.
fonte