Moda

Problemi

  • Se nessun valore si ripete?
  • Se ci sono due valori con la stessa frequenza massima?

1

Da Python 3.4: statistics.mode(z)

import statistics

NUMERI = [...]
m = statistics.mode(NUMERI)

2

Se l’intervallo di valori è noto, [0,  9]

  • utilizza una lista di 10 contatori (inizializzati a zero)
  • visita la lista aggiornando i contatori
  • individua il contatore più grande
  • la moda è l’indice del contatore più grande
def moda(lista):
    contatori = [0,0,0,0,0,0,0,0,0,0]
    for x in lista:
        contatori[x] += 1

    max_pos = 0
    max_val = contatori[0]
    for i in range(1, 10):
        x = contatori[i]
        if(x > max_val):
            max_val = x
            max_pos = i

    return max_pos

Soluzione 3

Se l’intervallo di valori non è noto

Osserva

  1. ordina la lista
  2. utilizza un contatore temporaneo
  3. conta quante volte compare ciascun valore
  4. memorizza il valore e la lunghezza della sequenza più lunga
  5. se nessun elemento compare almeno due volte restituisce errore (None).
LISTA=sorted(NUMERI)

x     =LISTA[0]
moda  =-1       # moda
modan =-1       # moda - numerosità
modat =x        # moda temporanea
modatn=1        # moda temporanea - numerosità

for i in range(1, len(LISTA)):
    x=LISTA[i]
    if(x == modat):
        modatn += 1
    else:
        if(modatn > modan):
            moda =modat
            modan=modatn
        modat =x
        modatn=1

if(modan < 2): 
    moda=None

Soluzione 4

Evita di trattare il primo valore in modo speciale

LISTA=sorted(NUMERI) 

moda  =-1  # moda 
modan =-1  # moda - numerosità 
modat =-1  # moda temporanea 
modatn=-1  # moda temporanea - numerosità 

for x in LISTA: 
    if(x == modat): 
        modatn += 1 
    else: 
        if(modatn > modan): 
            moda =modat 
            modan=modatn 
        modat =x 
        modatn=1 
if(modan < 2): 
    moda=None

Soluzione 5

Per non ordinare la lista utilizza un dizionario (dict)

def valore(coppia):
    return coppia[1]

def moda(lista):
    d={}
    for x in lista:
        d[x]=d.get(x,0)+1
    lista=list(d.items()) 
    lista.sort(key=valore, reverse=True)
    if(lista[0][1] >= 2):
        return lista[0][0]

lista1=[1,8,0, 1,  1,9,2, 8] 
lista2=[1,8,0,10,100,9,2,80] 
print(moda(lista1))          # 1 
print(moda(lista2))          # None

Soluzione 6

Utilizza un dizionario migliorato: Counter

import collections

NUMERI=[...]

counter = collections.Counter(NUMERI)
moda    = counter.most_common(1)[0][0]

print(moda)