7
votes

Calculer le mode dans une liste multimodale en python

J'essaie de calculer le mode (valeur la plus fréquente) d'une liste de valeurs dans Python. Je suis venu avec une solution, qui donnait de toute façon la mauvaise réponse, mais j'ai alors réalisé que mes données peuvent être mutlimodales; xxx

Voici ce que je suis arrivé jusqu'à présent: xxx

Je pense que le problème ici est que je suscite plutôt la valeur que le pointeur de la valeur maximale. Quoi qu'il en soit, quelqu'un peut-il suggérer une meilleure façon de faire cela qui pourrait fonctionner là où il y a plus d'un mode? Ou défaillonner que je peux réparer ce que j'ai jusqu'à présent et identifier un seul mode?

Comme vous pouvez probablement dire que je suis très nouveau à Python, merci pour l'aide. < p> Edit: aurait dû mentionner que je suis en python 2.4


1 commentaires

Vous devriez vraiment passer à la dernière version prise en charge de Python.


4 Réponses :


6
votes

in python> = 2.7, utilisez collections.Counter code > pour les tables de fréquence.

from collections import Counter
from itertools import takewhile

data = [1,1,2,3,4,4]
freq = Counter(data)
mostfreq = freq.most_common()
modes = list(takewhile(lambda x_f: x_f[1] == mostfreq[0][1], mostfreq))


3 commentaires

@Captastic: alors vous devriez vraiment mettre à niveau. Python 2.4 est de 2004; Même Python 2.5 ne reçoit plus des correctifs de sécurité.


Je serai perdu si je peux obtenir cette dernière ligne "Main-là" pour travailler sans SyntaxError sur ma version 3.2.3, mais je suis un débutant. Les pensées?


@Matthewcornell: Tuple Déballage dans les définitions de la fonction (y compris les Lambdas) a été supprimée en 3.2, ou peut-être même plus tôt. Je vais mettre à jour la réponse.



1
votes

Vous pouvez utiliser un compteur pour la valeur supérieure tout en itération, quelque chose comme ceci:

from heapq import nlargest
import operator

def mode(valueList, nmodes):
  frequencies = {}

  for value in valueList:
    frequencies[value] = frequencies.get(value, 0) + 1

  return [x[0] for x in nlargest(nmodes,frequencies.iteritems(),operator.itemgetter(1))]


2 commentaires

Cela ferait ça, merci. Bien que cela ne soit pas sûr, comment je le converties au travail avec plus d'un mode.


Merci pour l'entrée, je suis allé avec des expéditeurs, mais je devrai avoir une pièce de théâtre avec le vôtre si seulement pour l'expérience d'apprentissage.



5
votes

Eh bien, le premier problème est que oui, vous retournez la valeur dans fréquences plutôt que la clé. Cela signifie que vous obtenez le compter du mode, pas le mode lui-même. Normalement, pour obtenir le mode, vous utiliseriez la touche argument de mots-clés sur Max, comme: xxx

mais en 2.4 qui n'existe pas! Voici une approche que je crois travaillera en 2.4: xxx

i préférez l'idiome décorer-trier-indecore dans le mot clé CMP . Je pense que c'est plus lisible. Pourrait être c'est juste moi.


4 commentaires

Excellent merci, aussi j'aurais dû mentionner que je suis en 2.4. J'ai mis à jour le post.


@Captastic, Argh. Aucun DefaultDictDict , no compteur , et no clé argument sur max . Phew. Avoir à faire cela la solution difficile ... juste une seconde.


Dans py2.4, vous utiliseriez l'argument CMP sur max au lieu de la touche (qui n'existait pas encore); Donc, Mode = max (fréquences, CMP = Lambda I, J: CMP (comptes [i], compte [j])) .


@senderle c'est celui qui est! Ça marche merveilleusement. Merci beaucoup. Maintenant pour apprendre comment diable ça marche :)



5
votes

Notez que commencer Python 3.8 Code>, la bibliothèque standard inclut le statistiques.multimode code> fonction Pour renvoyer une liste des valeurs les plus fréquentes dans l'ordre dans lequel elles ont été rencontrées pour la première fois:

from statistics import multimode

multimode([1, 1, 2, 3, 4, 4])
# [1, 4]


0 commentaires