2015-04-28 26 views
6

Questo è più un problema di matematica che altro. Consente di assumere Ho due elenchi di diverse dimensioni in PythonPercentuale sovrapposizione di due elenchi

listA = ["Alice", "Bob", "Joe"] 
listB = ["Joe", "Bob", "Alice", "Ken"] 

voglio scoprire che cosa percentuale di sovrapposizione di questi due liste hanno. L'ordine non è importante all'interno degli elenchi. Trovare la sovrapposizione è facile, ho visto altri post su come farlo, ma non riesco a estenderlo nella mia mente per scoprire quale percentuale si sovrappongono. Se confrontassi le liste in diversi ordini, il risultato sarebbe diverso? Quale sarebbe il modo migliore per farlo?

+0

L'ordine non conta molto, tuttavia, è necessario prima definire la formula per la percentuale, potrebbe essere qualcosa del tipo: '2 * numero di corrispondenze/(len (lista) + len (listab))' o qualcos'altro – ZdaR

+1

Cosa succede se il lis ts sono '[1,1,1]' e '[1]'. La sovrapposizione sarebbe del 100% o del 33%? –

+0

Qual è l'output previsto per questi due elenchi? – Ofiris

risposta

4

La differenza massima si ha quando due elenchi hanno elementi completamente diversi. Quindi abbiamo al massimo n + m elementi discreti, dove n è la dimensione del primo elenco e m è la dimensione del secondo elenco. Una misura può essere:

2 * c/(n + m) 

dove c è il numero di elementi comuni. Questo può essere calcolato in questo modo in percentuale:

200.0 * len(set(listA) & set(listB))/(len(listA) + len(listB)) 
+0

Questo non riesce per il seguente esempio: listA = ["Alice", "Alice"] listB = ["Alice", "Alice"] –

2
>>> len(set(listA)&set(listB))/float(len(set(listA) | set(listB))) * 100 
75.0 

vorrei calcolare gli elementi comuni su un totale di elementi distinti.

len(set(listA)&set(listB)) restituisce gli elementi comuni (3 nell'esempio).

len(set(listA) | set(listB)) restituisce il numero totale di elementi distinti (4).

Moltiplica per 100 e ottieni la percentuale.

+0

Si noti che questa risposta e la risposta @JuniorCompressor sono diverse, entrambe corrette ma dipendono dal requisito specifico. – Ofiris

2

Dal principale punto di vista, direi che ci sono due domande sensate si potrebbe chiedere:

  1. Quale percentuale della sovrapposizione è se rispetto al primo lista? Cioè quanto è grande la parte comune rispetto alla prima lista?
  2. La stessa cosa per il secondo elenco.
  3. Qual è la percentuale di sovrapposizione rispetto all'universo (ovvero l'unione di entrambe le liste)?

Si possono trovare sicuramente altri significati e ce ne sarebbero molti. Tutto sommato, probabilmente dovresti sapere quale problema stai cercando di risolvere.

Dal punto di vista della programmazione, la soluzione è semplice:

listA = ["Alice", "Bob", "Joe"] 
listB = ["Joe", "Bob", "Alice", "Ken"] 

setA = set(listA) 
setB = set(listB) 

overlap = setA & setB 
universe = setA | setB 

result1 = float(len(overlap))/len(setA) * 100 
result2 = float(len(overlap))/len(setB) * 100 
result3 = float(len(overlap))/len(universe) * 100 
0
def computeOverlap(L1, L2): 
    d1, d2 = {}, {} 
    for e in L1: 
     if e not in d1: 
      d1[e] = 1 
     d1[e] += 1 

    for e in L2: 
     if e not in d2: 
      d2[e] = 0 
     d2[e] += 1 

    o1, o2 = 0, 0 
    for k in d1: 
     o1 += min(d1[k], d2.get(k,0)) 
    for k in d2: 
     o2 += min(d1.get(k,0), d2[k]) 

    print((100*o1) if o1 else 0 "% of the first list overlaps with the second list") 
    print((100*o2) if o2 else 0 "% of the second list overlaps with the first list") 

Naturalmente, si può solo fare questo con un defaultdict e un contatore, per rendere le cose un po 'più facile:

from collections import defaultdict, Counter 

def computeOverlap(L1, L2): 
    d1 = defaultdict(int, Counter(L1)) 
    d2 = defaultdict(int, Counter(L2)) 

    o1, o2 = 0, 0 
    for k in d1: 
     o1 += min(d1[k], d2[k]) 
    for k in d2: 
     o2 += min(d1[k,0], d2[k]) 

    print((100*o1) if o1 else 0 "% of the first list overlaps with the second list") 
    print((100*o2) if o2 else 0 "% of the second list overlaps with the first list") 
Problemi correlati