Buscar..


Introducción

En Python, el método itertools.groupby() permite a los desarrolladores agrupar los valores de una clase iterable basándose en una propiedad específica en otro conjunto de valores iterables.

Sintaxis

  • itertools.groupby (iterable, key = None o alguna función)

Parámetros

Parámetro Detalles
iterable Cualquier pitón iterable
llave Función (criterios) sobre la cual agrupar lo iterable.

Observaciones

groupby () es complicado pero una regla general a tener en cuenta al usarlo es la siguiente:

Ordene siempre los elementos que desea agrupar con la misma clave que desea utilizar para agrupar

Se recomienda que el lector revise la documentación aquí y vea cómo se explica utilizando una definición de clase.

Ejemplo 1

Di que tienes la cuerda

s = 'AAAABBBCCDAABBB'

y te gustaría dividirlo para que todas las 'A' estén en una lista y así con todas las 'B' y 'C', etc. Podrías hacer algo como esto

s = 'AAAABBBCCDAABBB'
s_dict = {}
for i in s:
    if i not in s_dict.keys():
        s_dict[i] = [i]
    else:
        s_dict[i].append(i)
s_dict

Resultados en

{'A': ['A', 'A', 'A', 'A', 'A', 'A'],
 'B': ['B', 'B', 'B', 'B', 'B', 'B'],
 'C': ['C', 'C'],
 'D': ['D']}

Pero para un conjunto de datos de gran tamaño, estaría acumulando estos elementos en la memoria. Aquí es donde entra groupby ()

Podríamos obtener el mismo resultado de una manera más eficiente haciendo lo siguiente

# note that we get a {key : value} pair for iterating over the items just like in python dictionary
from itertools import groupby
s = 'AAAABBBCCDAABBB'
c = groupby(s)

dic = {} 
for k, v in c:
    dic[k] = list(v)
dic

Resultados en

{'A': ['A', 'A'], 'B': ['B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']}

Observe que el número de 'A's en el resultado cuando usamos group by es menor que el número real de' A's en la cadena original. Podemos evitar esa pérdida de información ordenando los elementos en s antes de pasarlos a c como se muestra a continuación

c = groupby(sorted(s))

dic = {} 
for k, v in c:
    dic[k] = list(v)
dic

Resultados en

{'A': ['A', 'A', 'A', 'A', 'A', 'A'], 'B': ['B', 'B', 'B', 'B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']}

Ahora tenemos todas nuestras 'A's.

Ejemplo 2

Este ejemplo ilustra cómo se elige la clave predeterminada si no especificamos ninguna

c = groupby(['goat', 'dog', 'cow', 1, 1, 2, 3, 11, 10, ('persons', 'man', 'woman')])
dic = {}
for k, v in c:
    dic[k] = list(v)
dic

Resultados en

{1: [1, 1],
 2: [2],
 3: [3],
 ('persons', 'man', 'woman'): [('persons', 'man', 'woman')],
 'cow': ['cow'],
 'dog': ['dog'],
 10: [10],
 11: [11],
 'goat': ['goat']}

Observe aquí que la tupla en su conjunto cuenta como una clave en esta lista

Ejemplo 3

Note en este ejemplo que mulato y camello no aparecen en nuestro resultado. Sólo se muestra el último elemento con la clave especificada. El último resultado para c en realidad borra dos resultados anteriores. Pero mira la nueva versión donde tengo los datos ordenados primero en la misma clave.

list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \
               'wombat', 'mongoose', 'malloo', 'camel']
c = groupby(list_things, key=lambda x: x[0])
dic = {}
for k, v in c:
    dic[k] = list(v)
dic

Resultados en

{'c': ['camel'],
 'd': ['dog', 'donkey'],
 'g': ['goat'],
 'm': ['mongoose', 'malloo'],
 'persons': [('persons', 'man', 'woman')],
 'w': ['wombat']}

Versión ordenada

list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \
               'wombat', 'mongoose', 'malloo', 'camel']
sorted_list = sorted(list_things, key = lambda x: x[0])
print(sorted_list)
print()
c = groupby(sorted_list, key=lambda x: x[0])
dic = {}
for k, v in c:
    dic[k] = list(v)
dic

Resultados en

['cow', 'cat', 'camel', 'dog', 'donkey', 'goat', 'mulato', 'mongoose', 'malloo', ('persons', 'man', 'woman'), 'wombat']

{'c': ['cow', 'cat', 'camel'],
 'd': ['dog', 'donkey'],
 'g': ['goat'],
 'm': ['mulato', 'mongoose', 'malloo'],
 'persons': [('persons', 'man', 'woman')],
 'w': ['wombat']}

Ejemplo 4

En este ejemplo, vemos lo que sucede cuando usamos diferentes tipos de iterable.

things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "harley"), \
          ("vehicle", "speed boat"), ("vehicle", "school bus")]
dic = {}
f = lambda x: x[0]
for key, group in groupby(sorted(things, key=f), f):
    dic[key] = list(group)
dic

Resultados en

{'animal': [('animal', 'bear'), ('animal', 'duck')],
 'plant': [('plant', 'cactus')],
 'vehicle': [('vehicle', 'harley'),
  ('vehicle', 'speed boat'),
  ('vehicle', 'school bus')]}

Este ejemplo a continuación es esencialmente el mismo que el de arriba. La única diferencia es que he cambiado todas las tuplas a listas.

things = [["animal", "bear"], ["animal", "duck"], ["vehicle", "harley"], ["plant", "cactus"], \
          ["vehicle", "speed boat"], ["vehicle", "school bus"]]
dic = {}
f = lambda x: x[0]
for key, group in groupby(sorted(things, key=f), f):
    dic[key] = list(group)
dic

Resultados

{'animal': [['animal', 'bear'], ['animal', 'duck']],
 'plant': [['plant', 'cactus']],
 'vehicle': [['vehicle', 'harley'],
  ['vehicle', 'speed boat'],
  ['vehicle', 'school bus']]}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow