Pergunta

Eu quero listas de classificação múltiplas de acordo com os seus elementos quantas vezes eles aparecem em cada lista. Exemplo:

list1 = 1,2,3,4
list2 = 4,5,6,7
list3 = 4,1,8,9

= resultado 4,1,2,3,4,5,6,7,8 (4 é contada três vezes, 1 duas vezes e uma vez que o resto)

Eu tentei o seguinte mas eu preciso de algo mais inteligente e algo que eu posso fazer com qualquer ammount de listas.


 l = []
 l.append([ 1, 2, 3, 4, 5])
 l.append([ 1, 9, 3, 4, 5])
 l.append([ 1, 10, 8, 4, 5])
 l.append([ 1, 12, 13, 7, 5])
 l.append([ 1, 14, 13, 13, 6])

 x1 = set(l[0]) & set(l[1]) & set(l[2]) & set(l[3])
 x2 = set(l[0]) & set(l[1]) & set(l[2]) & set(l[4])
 x3 = set(l[0]) & set(l[1]) & set(l[3]) & set(l[4])
 x4 = set(l[0]) & set(l[2]) & set(l[3]) & set(l[4])
 x5 = set(l[1]) & set(l[2]) & set(l[3]) & set(l[4])
 set1 = set(x1) | set(x2) | set(x3) | set(x4) | set(x5)

 a1 = list(set(l[0]) & set(l[1]) & set(l[2]) & set(l[3]) & set(l[4]))
 a2 = getDifference(list(set1),a1)
 print a1
 print a2

Agora, aqui está o problema ... eu posso fazê-lo novamente e novamente com o A3, A4 e A5, mas a sua demasiado complexo, em seguida, eu preciso de uma função para isso ... Mas eu não sei como ... o meu matemática ficou preso;)

resolvido: muito obrigado para a discussão. Como i newbee como este sistema de alguma forma: fast + informativo. Você me ajudou todos para fora! Ty

Foi útil?

Solução

import collections

data = [
  [1, 2, 3, 4, 5],
  [1, 9, 3, 4, 5],
  [1, 10, 8, 4, 5],
  [1, 12, 13, 7, 5],
  [1, 14, 13, 13, 6],
]

def sorted_by_count(lists):
  counts = collections.defaultdict(int)
  for L in lists:
    for n in L:
      counts[n] += 1

  return [num for num, count in
          sorted(counts.items(),
                 key=lambda k_v: (k_v[1], k_v[0]),
                 reverse=True)]

print sorted_by_count(data)

Agora vamos generalizar-lo (para tomar qualquer, exigência Hashable soltar iterable), permite que os parâmetros-chave e reversa (para combinar classificadas), e renomeie a freq_sorted :

def freq_sorted(iterable, key=None, reverse=False, include_freq=False):
  """Return a list of items from iterable sorted by frequency.

  If include_freq, (item, freq) is returned instead of item.

  key(item) must be hashable, but items need not be.

  *Higher* frequencies are returned first.  Within the same frequency group,
  items are ordered according to key(item).
  """
  if key is None:
    key = lambda x: x

  key_counts = collections.defaultdict(int)
  items = {}
  for n in iterable:
    k = key(n)
    key_counts[k] += 1
    items.setdefault(k, n)

  if include_freq:
    def get_item(k, c):
      return items[k], c
  else:
    def get_item(k, c):
      return items[k]

  return [get_item(k, c) for k, c in
          sorted(key_counts.items(),
                 key=lambda kc: (-kc[1], kc[0]),
                 reverse=reverse)]

Exemplo:

>>> import itertools
>>> print freq_sorted(itertools.chain.from_iterable(data))
[1, 5, 4, 13, 3, 2, 6, 7, 8, 9, 10, 12, 14]
>>> print freq_sorted(itertools.chain.from_iterable(data), include_freq=True)
# (slightly reformatted)
[(1, 5),
 (5, 4),
 (4, 3), (13, 3),
 (3, 2),
 (2, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1), (12, 1), (14, 1)]

Outras dicas

combinando um par de ideias já postou:

from itertools import chain
from collections import defaultdict

def frequency(*lists):
    counter = defaultdict(int)
    for x in chain(*lists):
        counter[x] += 1
    return [key for (key, value) in 
        sorted(counter.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)]

Notas:

  1. Em Python 2.7, você pode usar Counter vez de defaultdict(int).
  2. Esta versão leva qualquer número de listas como seu argumento; os meios principais asterisco todos eles vão ser embalado em uma tupla. Se você quer passar em uma única lista contendo todas as suas listas, omitir que liderar asterisco.
  3. Isto quebra se suas listas contêm um tipo unhashable.
def items_ordered_by_frequency(*lists):

    # get a flat list with all the values
    biglist = []
    for x in lists:
        biglist += x

    # sort it in reverse order by frequency
    return sorted(set(biglist), 
                  key=lambda x: biglist.count(x), 
                  reverse=True)

Tente esta:

def rank(*lists):
    d = dict()
    for lst in lists:
        for e in lst:
            if e in d: d[e] += 1
            else: d[e] = 1
    return [j[1] for j in sorted([(d[i],i) for i in d], reverse=True)]

Exemplo de uso:

a = [1,2,3,4]
b = [4,5,6,7]
c = [4,1,8,9]

print rank(a,b,c)

Você pode usar qualquer número de listas como entrada

Você pode contar o número de aparições de cada elemento (um histograma), em seguida, classificar por ela:

def histogram(enumerable):
  result = {}
  for x in enumerable:
    result.setdefault(x, 0)
    result[x] += 1
  return result

lists = [ [1,2,3,4], [4,5,6,7], ... ]

from itertools import chain

h = histogram(chain(*lists))
ranked = sorted(set(chain(*lists)), key = lambda x : h[x], reverse = True)

Tente este código:

def elementFreq(myList):
    #myList is the list of lists
    from collections import Counter
    tmp = []
    for i in myList: tmp += i        
    return(Counter(tmp))

Nota: Suas listas devem ser do tipo Hashable

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top