Wie verwende ich Python itertools.groupby ()?

stimmen
364

Ich habe nicht in der Lage gewesen , eine verständliche Erklärung, wie zu finden , um tatsächlich Python verwenden itertools.groupby()Funktion. Was ich versuche , dies zu tun:

  • Machen Sie eine Liste - in diesem Fall die Kinder eines objektivierten lxmlElement
  • Teilen Sie es in Gruppen auf der Grundlage einiger Kriterien
  • Dann durchläuft später separat jede dieser Gruppen über.

Ich habe überprüft die Dokumentation und die Beispiele , aber ich habe Mühe hatte , zu versuchen , sie über eine einfache Liste von Zahlen anzuwenden.

Also, wie ich verwenden itertools.groupby()? Gibt es eine andere Technik , die ich verwenden sollte? Zeiger auf eine gute „Voraussetzung“ Lesen würde auch geschätzt werden.

Veröffentlicht am 03/08/2008 um 19:27
quelle vom benutzer
In anderen Sprachen...                            


13 antworten

stimmen
523

Wie Sebastjan sagte, müssen Sie zunächst Ihre Daten sortieren. Das ist wichtig.

Der Teil habe ich nicht bekommen, ist, dass in dem Beispiel Bau

groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
   groups.append(list(g))    # Store group iterator as a list
   uniquekeys.append(k)

kist der aktuelle Gruppierungsschlüssel, und gist ein Iterator , die Sie über die Gruppe verwenden können , von dieser Gruppierung Schlüsseln definiert iterieren. Mit anderen Worten, der groupbyIterator selbst kehrt Iteratoren.

Hier ist ein Beispiel dafür, klare Variablennamen verwenden:

from itertools import groupby

things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")]

for key, group in groupby(things, lambda x: x[0]):
    for thing in group:
        print "A %s is a %s." % (thing[1], key)
    print " "

Dies gibt Ihnen die Ausgabe:

Ein Bär ist ein Tier.
Eine Ente ist ein Tier.

Ein Kaktus ist eine Pflanze.

Ein Schnellboot ist ein Fahrzeug.
Ein Schulbus ist ein Fahrzeug.

In diesem Beispiel thingsist eine Liste von Tupeln , wo das erste Element in jedem Tupel der Gruppe ist das zweite Element gehört.

Die groupby()Funktion nimmt zwei Argumente: (1) die Daten zu gruppieren und (2) die Funktion zur Gruppe mit.

Hier lambda x: x[0]erzählt groupby()das erste Element in jedem Tupel als Gruppierungsschlüssel zu verwenden.

In der obigen forAnweisung groupbygibt drei (Schlüssel, Gruppe Iterator) Paare - einmal für jeden eindeutigen Schlüssel. Sie können die zurückgegebene Iterator verwenden , um jedes einzelne Element in dieser Gruppe iterieren.

Hier ist ein etwas anderes Beispiel mit den gleichen Daten, eine Liste Verständnis mit:

for key, group in groupby(things, lambda x: x[0]):
    listOfThings = " and ".join([thing[1] for thing in group])
    print key + "s:  " + listOfThings + "."

Dies gibt Ihnen die Ausgabe:

Tiere: Bär und Ente.
Pflanzen: Kakteen.
Fahrzeuge: Schnellboot und Schulbus.

Beantwortet am 10/08/2008 um 19:45
quelle vom benutzer

stimmen
65

Können Sie uns Ihren Code zeigen?

Das Beispiel auf der Python-Dokumentation ist ziemlich einfach:

groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
    groups.append(list(g))      # Store group iterator as a list
    uniquekeys.append(k)

Also in Ihrem Fall werden die Daten eine Liste von Knoten ist, ist keyfunc , wo die Logik Ihrer Kriterien Funktion geht und dann groupby()die Datengruppen.

Sie müssen vorsichtig sein , um die Daten zu sortieren nach den Kriterien , bevor Sie anrufen groupbyoder es wird nicht funktionieren. groupbyVerfahren eigentlich nur eine Iteration durch eine Liste und wann immer die wichtigsten Veränderungen , die sie eine neue Gruppe erstellt.

Beantwortet am 03/08/2008 um 19:40
quelle vom benutzer

stimmen
32

Ein neato Trick mit groupby ist Längencodierung in einer Zeile auszuführen:

[(c,len(list(cgen))) for c,cgen in groupby(some_string)]

finden Sie eine Liste von 2-Tupeln geben, wo das erste Element das Zeichen und das zweite ist die Anzahl der Wiederholungen.

Edit: Beachten Sie, dass das ist , was trennt itertools.groupbyvon der SQL - GROUP BYSemantik: itertools nicht (und in der Regel nicht) sortieren Sie den Iterator im Voraus, so dass Gruppen mit dem gleichen „Schlüssel“ ist nicht verschmolzen.

Beantwortet am 01/09/2008 um 00:27
quelle vom benutzer

stimmen
21

Ein anderes Beispiel:

for key, igroup in itertools.groupby(xrange(12), lambda x: x // 5):
    print key, list(igroup)

Ergebnisse in

0 [0, 1, 2, 3, 4]
1 [5, 6, 7, 8, 9]
2 [10, 11]

Beachten Sie, dass igroup ist ein Iterator (ein Teil Iterator als die Dokumentation es nennt).

Dies ist nützlich für Chunking einen Generator:

def chunker(items, chunk_size):
    '''Group items in chunks of chunk_size'''
    for _key, group in itertools.groupby(enumerate(items), lambda x: x[0] // chunk_size):
        yield (g[1] for g in group)

with open('file.txt') as fobj:
    for chunk in chunker(fobj):
        process(chunk)

Ein weiteres Beispiel für groupby - wenn die Schlüssel nicht sortiert werden. Im folgenden Beispiel werden Elemente im xx durch Werte in yy gruppiert. In diesem Fall ist ein Satz von Nullen zuerst ausgegeben, durch eine Reihe von Einsen, gefolgt wiederum von einer Reihe von Nullen.

xx = range(10)
yy = [0, 0, 0, 1, 1, 1, 0, 0, 0, 0]
for group in itertools.groupby(iter(xx), lambda x: yy[x]):
    print group[0], list(group[1])

produziert:

0 [0, 1, 2]
1 [3, 4, 5]
0 [6, 7, 8, 9]
Beantwortet am 21/01/2013 um 17:54
quelle vom benutzer

stimmen
17

WARNUNG:

Die Syntax-Liste (groupby (...)) wird nicht so funktionieren, dass Sie beabsichtigen. Es scheint, die internen Iterator Objekte zu zerstören, so verwenden

for x in list(groupby(range(10))):
    print(list(x[1]))

wird herstellen:

[]
[]
[]
[]
[]
[]
[]
[]
[]
[9]

Stattdessen die Liste (groupby (...)), versuchen Sie [(k, Liste (g)) für k, g in groupby (...)], oder wenn Sie diese Syntax häufig verwenden,

def groupbylist(*args, **kwargs):
    return [(k, list(g)) for k, g in groupby(*args, **kwargs)]

und erhalten Sie Zugang zum groupby Funktionalität während jene nervtötende (für kleine Daten) zu vermeiden Iteratoren alle zusammen.

Beantwortet am 16/11/2013 um 01:39
quelle vom benutzer

stimmen
11

itertools.groupby ist ein Werkzeug, Elemente für die Gruppierung.

Aus der Dokumentation , aufzulesen wir weiter , was sie tun könnten:

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B

# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D

groupby Objekte ergeben Schlüsselgruppenpaare in dem die Gruppe ein Generator ist.

Eigenschaften

  • A. Gruppe aufeinander folgende Elemente zusammen (ähnlich das unique_justseenRezept)
  • B. Gruppe alle Vorkommen eines Elements, da eine sortierte iterable
  • C. Geben Sie, wie man Gruppenelemente mit einer Schlüsselfunktion

Vergleiche

# Define a printer for comparing outputs
>>> def print_groupby(iterable, key=None):
...    for k, g in it.groupby(iterable, key):
...        print("key: '{}'--> group: {}".format(k, list(g)))


# Feature A: group consecutive occurrences
>>> print_groupby("BCAACACAADBBB")
key: 'B'--> group: ['B']
key: 'C'--> group: ['C']
key: 'A'--> group: ['A', 'A']
key: 'C'--> group: ['C']
key: 'A'--> group: ['A']
key: 'C'--> group: ['C']
key: 'A'--> group: ['A', 'A']
key: 'D'--> group: ['D']
key: 'B'--> group: ['B', 'B', 'B']

# Feature B: group all occurrences
>>> print_groupby(sorted("BCAACACAADBBB"))
key: 'A'--> group: ['A', 'A', 'A', 'A', 'A']
key: 'B'--> group: ['B', 'B', 'B', 'B']
key: 'C'--> group: ['C', 'C', 'C']
key: 'D'--> group: ['D']

# Feature C: group by a key
>>> key = lambda x: x.islower()
>>> print_groupby(sorted("bCAaCacAADBbB"), key)
key: 'False'--> group: ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']
key: 'True'--> group: ['a', 'a', 'b', 'b', 'c']

Verwendet

Einige der letzteren Beispiele stammen aus Víctor Terrón der PyCon Vortrag (Englisch) (Spanisch) , Kung Fu an der Dämmerung mit itertools . Für alle Interessierten, hier ist der Quellcode für die groupbyin C geschrieben

Beantwortet am 25/08/2017 um 02:26
quelle vom benutzer

stimmen
10

Ich möchte ein weiteres Beispiel geben, wo groupby ohne Art nicht funktioniert. Angepasst von Beispiel von James Sulak

from itertools import groupby

things = [("vehicle", "bear"), ("animal", "duck"), ("animal", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")]

for key, group in groupby(things, lambda x: x[0]):
    for thing in group:
        print "A %s is a %s." % (thing[1], key)
    print " "

Ausgang

A bear is a vehicle.

A duck is a animal.
A cactus is a animal.

A speed boat is a vehicle.
A school bus is a vehicle.

gibt es zwei Gruppen mit Vehicule, während man nur eine Gruppe erwarten könnte

Beantwortet am 07/05/2013 um 21:09
quelle vom benutzer

stimmen
7

@CaptSolo, habe ich versucht, Ihr Beispiel, aber es hat nicht funktioniert.

from itertools import groupby 
[(c,len(list(cs))) for c,cs in groupby('Pedro Manoel')]

Ausgabe:

[('P', 1), ('e', 1), ('d', 1), ('r', 1), ('o', 1), (' ', 1), ('M', 1), ('a', 1), ('n', 1), ('o', 1), ('e', 1), ('l', 1)]

Wie Sie sehen können, gibt es zwei O und zwei E ist, aber sie haben in getrennte Gruppen. Das ist, wenn ich merkte, müssen Sie die Liste der groupby Funktion übergeben sortieren. So wäre die korrekte Verwendung sein:

name = list('Pedro Manoel')
name.sort()
[(c,len(list(cs))) for c,cs in groupby(name)]

Ausgabe:

[(' ', 1), ('M', 1), ('P', 1), ('a', 1), ('d', 1), ('e', 2), ('l', 1), ('n', 1), ('o', 2), ('r', 1)]

Nur die Erinnerung, wenn die Liste nicht sortiert ist, die groupby Funktion wird nicht funktionieren !

Beantwortet am 15/10/2009 um 16:41
quelle vom benutzer

stimmen
5

Wie verwende ich Python itertools.groupby ()?

Sie können groupby gruppieren Dinge verwenden , um durchlaufen. Sie geben groupby ein iterable und eine optionale Tastenfunktion / aufrufbar , mit denen die Einzelteile zu überprüfen , wie sie aus dem iterable kommen, und es gibt einen Iterator, der eine zwei-Tupel des Ergebnisses des Schlüssels aufrufbar und den tatsächlich gibt in eine andere iterable. Von der Hilfe:

groupby(iterable[, keyfunc]) -> create an iterator which returns
(key, sub-iterator) grouped by each value of key(value).

Hier ist ein Beispiel von groupby eine Koroutine zur Gruppe durch eine Zählung verwendet wird , verwendet es einen Schlüssel aufrufbar (in diesem Fall coroutine.send) nur ausspucken die Zählung für jedoch viele Iterationen und ein gruppierte Unter Iterator der Elemente:

import itertools


def grouper(iterable, n):
    def coroutine(n):
        yield # queue up coroutine
        for i in itertools.count():
            for j in range(n):
                yield i
    groups = coroutine(n)
    next(groups) # queue up coroutine

    for c, objs in itertools.groupby(iterable, groups.send):
        yield c, list(objs)
    # or instead of materializing a list of objs, just:
    # return itertools.groupby(iterable, groups.send)

list(grouper(range(10), 3))

Druck

[(0, [0, 1, 2]), (1, [3, 4, 5]), (2, [6, 7, 8]), (3, [9])]
Beantwortet am 27/07/2015 um 18:06
quelle vom benutzer

stimmen
3

Sortier- und groupby

from itertools import groupby

val = [{'name': 'satyajit', 'address': 'btm', 'pin': 560076}, {'name': 'Mukul', 'address': 'Silk board', 'pin': 560078}, {'name': 'Preetam', 'address': 'btm', 'pin': 560076}]


for pin, list_data in groupby(sorted(val, key=lambda k: k['pin']),lambda x: x['pin']):
...     print pin
...     for rec in list_data:
...             print rec
... 
o/p:

560076
{'name': 'satyajit', 'pin': 560076, 'address': 'btm'}
{'name': 'Preetam', 'pin': 560076, 'address': 'btm'}
560078
{'name': 'Mukul', 'pin': 560078, 'address': 'Silk board'}
Beantwortet am 01/08/2017 um 07:14
quelle vom benutzer

stimmen
2

Ein nützliches Beispiel, das ich zufällig stieß kann hilfreich sein:

from itertools import groupby

#user input

myinput = input()

#creating empty list to store output

myoutput = []

for k,g in groupby(myinput):

    myoutput.append((len(list(g)),int(k)))

print(*myoutput)

Abtastwerteingang: 14445221

Beispielausgabe: (1,1) (3,4) (1,5) (2,2) (1,1)

Beantwortet am 18/06/2017 um 17:16
quelle vom benutzer

stimmen
1

Sie können eigene groupby Funktion schreiben:

           def groupby(data):
                kv = {}
                for k,v in data:
                    if k not in kv:
                         kv[k]=[v]
                    else:
                        kv[k].append(v)
           return kv

     Run on ipython:
       In [10]: data = [('a', 1), ('b',2),('a',2)]

        In [11]: groupby(data)
        Out[11]: {'a': [1, 2], 'b': [2]}
Beantwortet am 10/10/2018 um 17:53
quelle vom benutzer

stimmen
-1

Vereinbaren Sie einen Iterator, der aufeinander folgenden Tasten und Gruppen aus der iterable zurückgibt. Der Schlüssel ist eine Funktion, einen Schlüsselwert für jedes Element berechnet wird.

import itertools

for k,group in  itertools.groupby([['subject1','english'],['subject2','kannada']]):
for g in group:
    print(f'{k[0]} is {g[1]}')
# output : 
subject1 is english
subject2 is kannada
Beantwortet am 23/08/2018 um 06:44
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more