Πώς μπορώ να χρησιμοποιήσω itertools.groupby της Python ();

ψήφοι
364

Δεν ήμουν σε θέση να βρει μια κατανοητή εξήγηση για το πώς να χρησιμοποιούν πραγματικά Python του itertools.groupby()λειτουργία. Αυτό που προσπαθώ να κάνω είναι το εξής:

  • Πάρτε μια λίστα - σε αυτήν την περίπτωση, τα παιδιά ενός αντικειμενοποιημένης lxmlστοιχείου
  • Χωρίστε το σε ομάδες με βάση ορισμένα κριτήρια
  • Αργότερα επαναλάβει πάνω από κάθε μία από αυτές τις ομάδες ξεχωριστά.

Ελέγξαμε την τεκμηρίωση και τα παραδείγματα , αλλά είχα πρόβλημα να προσπαθεί να τις εφαρμόσει πέρα από μια απλή λίστα με τους αριθμούς.

Έτσι, πώς μπορώ να χρησιμοποιήσω της itertools.groupby(); Είναι μια άλλη τεχνική που θα πρέπει να χρησιμοποιούν εκεί; Δείκτες για την καλή ανάγνωση «προϋπόθεση» θα πρέπει επίσης να εκτιμηθεί.

Δημοσιεύθηκε 03/08/2008 στις 19:27
πηγή χρήστη
Σε άλλες γλώσσες...                            


13 απαντήσεις

ψήφοι
523

Όπως είπε ο Sebastjan, πρέπει πρώτα να ταξινομήσετε τα δεδομένα σας. Αυτό είναι σημαντικό.

Το μέρος δεν είχα είναι ότι το παράδειγμα των κατασκευών

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

kείναι το τρέχον κλειδί ομαδοποίηση, και gείναι ένα iterator που μπορείτε να χρησιμοποιήσετε για να επαναλάβει πάνω από την ομάδα που ορίζεται από αυτό το κλειδί ομάδα. Με άλλα λόγια, η groupbyίδια η iterator επιστρέφει επαναλήπτες.

Εδώ είναι ένα παράδειγμα ότι, χρησιμοποιώντας σαφέστερη ονόματα των μεταβλητών:

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 " "

Αυτό θα σας δώσει την έξοδο:

Μια αρκούδα είναι ένα ζώο.
Μια πάπια είναι ένα ζώο.

Ένα κάκτος είναι ένα φυτό.

Ένα σκάφος η ταχύτητα είναι ένα όχημα.
Ένα σχολικό λεωφορείο είναι ένα όχημα.

Σε αυτό το παράδειγμα, thingsείναι ένας κατάλογος των πλειάδες όπου το πρώτο στοιχείο σε κάθε πλειάδα είναι η ομάδα η δεύτερη στοιχείο ανήκει.

Η groupby()λειτουργία παίρνει δύο επιχειρήματα: (1) τα δεδομένα στην ομάδα και (2) τη λειτουργία στην ομάδα με.

Εδώ, lambda x: x[0]λέει groupby()να χρησιμοποιήσει το πρώτο στοιχείο σε κάθε πλειάδα ως βασική ομαδοποίηση.

Στην παραπάνω forδήλωση groupbyεπιστρέφει τρία (κλειδί, ομάδα iterator) ζεύγη - μία φορά για κάθε μοναδικό κλειδί. Μπορείτε να χρησιμοποιήσετε τη επέστρεψε iterator να επαναλάβει πάνω από κάθε μεμονωμένο στοιχείο σε αυτή την ομάδα.

Εδώ είναι ένα ελαφρώς διαφορετικό παράδειγμα με τα ίδια στοιχεία, χρησιμοποιώντας μια λίστα με κατανόηση:

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

Αυτό θα σας δώσει την έξοδο:

ζώα: αρκούδα και πάπια.
φυτά: κάκτος.
οχήματα: ταχύπλοο και σχολικό λεωφορείο.

Απαντήθηκε 10/08/2008 στις 19:45
πηγή χρήστη

ψήφοι
65

Μπορείτε να μας δείξει τον κωδικό σας;

Το παράδειγμα για τα έγγραφα Python είναι αρκετά απλή:

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

Έτσι, στην περίπτωσή σας, τα δεδομένα είναι μια λίστα των κόμβων, keyfunc είναι όπου η λογική των κριτηρίων σας λειτουργία πηγαίνει και, στη συνέχεια, groupby()ομάδες των δεδομένων.

Πρέπει να είστε προσεκτικοί για να ταξινομήσετε τα δεδομένα από τα κριτήρια πριν να καλέσετε groupbyή δεν θα λειτουργήσει. groupbyμέθοδος στην πραγματικότητα απλώς επαναλαμβάνει μέσα από μια λίστα και κάθε φορά που οι βασικές αλλαγές που δημιουργεί μια νέα ομάδα.

Απαντήθηκε 03/08/2008 στις 19:40
πηγή χρήστη

ψήφοι
32

Ένα neato κόλπο με groupby είναι να τρέξει το μήκος κωδικοποίησης σε μία γραμμή:

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

θα σας δώσει μια λίστα με 2-πλειάδες όπου το πρώτο στοιχείο είναι το κάρβουνο και το 2ο είναι ο αριθμός των επαναλήψεων.

Επεξεργασία: Σημειώστε ότι αυτό είναι ό, τι χωρίζει itertools.groupbyαπό το SQL GROUP BYσημασιολογία: itertools δεν (και εν γένει δεν μπορεί) να ταξινομήσετε τη iterator εκ των προτέρων, έτσι ώστε ομάδες με το ίδιο «κλειδί» δεν συγχωνεύονται.

Απαντήθηκε 01/09/2008 στις 00:27
πηγή χρήστη

ψήφοι
21

Ενα άλλο παράδειγμα:

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

αποτελέσματα σε

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

Σημειώστε ότι igroup είναι ένας iterator (μια υπο-iterator όπως η τεκμηρίωση αποκαλεί).

Αυτό είναι χρήσιμο για την κατάτμηση μιας γεννήτριας:

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)

Ένα άλλο παράδειγμα της groupby - όταν δεν έχουν υποστεί διαλογή τα πλήκτρα. Στο ακόλουθο παράδειγμα, τα αντικείμενα στο xx ομαδοποιημένες κατά τιμές σε yy. Στην περίπτωση αυτή, ένα σύνολο από μηδενικά εξάγεται πρώτα, που ακολουθείται από ένα σύνολο αυτά, που ακολουθείται και πάλι από μια σειρά από μηδενικά.

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])

παράγει:

0 [0, 1, 2]
1 [3, 4, 5]
0 [6, 7, 8, 9]
Απαντήθηκε 21/01/2013 στις 17:54
πηγή χρήστη

ψήφοι
17

ΠΡΟΕΙΔΟΠΟΙΗΣΗ:

Ο κατάλογος σύνταξη (groupby (...)) δεν θα λειτουργήσει με τον τρόπο που σκοπεύετε. Φαίνεται να καταστρέψει τα εσωτερικά αντικείμενα iterator, οπότε η χρήση

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

θα παράγει:

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

Αντ 'αυτού, της λίστας (groupby (...)), προσπαθήστε [(k, κατάλογος (ζ)) για το k, g σε groupby (...)], ή αν χρησιμοποιείτε αυτή την σύνταξη συχνά,

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

και αποκτήστε πρόσβαση στις λειτουργίες groupby αποφεύγοντας εκείνους τους ενοχλητικούς (για μικρά στοιχεία) επαναλήπτες όλοι μαζί.

Απαντήθηκε 16/11/2013 στις 01:39
πηγή χρήστη

ψήφοι
11

itertools.groupby είναι ένα μέσο για τη συγκέντρωση στοιχείων.

Από τα έγγραφα , έχουμε μαζέψει περαιτέρω τι μπορεί να κάνει:

# [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 αντικείμενα αποδώσει ζεύγη κλειδιού-ομάδα όπου η ομάδα είναι μια γεννήτρια.

Χαρακτηριστικά

  • Α Ομάδα συνεχόμενες στοιχεία μαζί (παρόμοιο με το unique_justseenσυνταγή)
  • Β Ομάδα όλες τις εμφανίσεις ενός στοιχείου, δίνεται μία ταξινομημένη iterable
  • Γ Καθορίστε τον τρόπο ομαδοποίησης αντικειμένων με ένα πλήκτρο λειτουργίας

συγκρίσεις

# 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']

χρήσεις

Αρκετά από τα τελευταία παραδείγματα προέρχονται από PyCon ομιλία Víctor Terrón του (Αγγλικά) (Ισπανικά) , Kung Fu στην Αυγή με Itertools . Για όσους ενδιαφέρονται, εδώ είναι ο πηγαίος κώδικας για την groupbyγραμμένο σε C.

Απαντήθηκε 25/08/2017 στις 02:26
πηγή χρήστη

ψήφοι
10

Θα ήθελα να δώσω ένα άλλο παράδειγμα όπου groupby χωρίς είδους δεν λειτουργεί. Προσαρμοσμένος από το παράδειγμα του 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 " "

εξόδου είναι

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.

υπάρχουν δύο ομάδες με ΟΧΗΜΑ, ενώ θα περίμενε κανείς μόνο μία ομάδα

Απαντήθηκε 07/05/2013 στις 21:09
πηγή χρήστη

ψήφοι
7

@CaptSolo, δοκίμασα το παράδειγμά σας, αλλά δεν λειτούργησε.

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

Παραγωγή:

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

Όπως μπορείτε να δείτε, υπάρχουν δύο o και δύο ε, αλλά πήραν σε ξεχωριστές ομάδες. Αυτό είναι, όταν συνειδητοποίησα θα πρέπει να ταξινομήσετε τη λίστα περάσει στη λειτουργία groupby. Έτσι, η σωστή χρήση θα είναι:

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

Παραγωγή:

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

Απλά να θυμάστε, εάν η λίστα δεν είναι ταξινομημένη, η λειτουργία groupby δεν θα λειτουργήσει !

Απαντήθηκε 15/10/2009 στις 16:41
πηγή χρήστη

ψήφοι
5

Πώς μπορώ να χρησιμοποιήσω itertools.groupby της Python ();

Μπορείτε να χρησιμοποιήσετε groupby τα πράγματα ομάδα να επαναλάβει πάνω. Δίνετε groupby μια iterable, και ένα προαιρετικό κλειδί λειτουργίας / απαιτητών με την οποία για να ελέγξετε τα στοιχεία που έρχονται από το iterable, και επιστρέφει ένα iterator που δίνει ένα δύο-πλειάδα του αποτελέσματος του κλειδιού απαιτητών και τα πραγματικά στοιχεία στα άλλο iterable. Από τη βοήθεια:

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

Εδώ είναι ένα παράδειγμα groupby χρησιμοποιώντας ένα coroutine στην ομάδα από την καταμέτρηση, χρησιμοποιεί ένα κλειδί απαιτητών (σε αυτή την περίπτωση, coroutine.send) σε μόλις φτύσει τον αριθμό για όσο πολλές επαναλήψεις και ομαδοποιούνται υπο-iterator των στοιχείων:

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))

εκτυπώσεις

[(0, [0, 1, 2]), (1, [3, 4, 5]), (2, [6, 7, 8]), (3, [9])]
Απαντήθηκε 27/07/2015 στις 18:06
πηγή χρήστη

ψήφοι
3

Ταξινόμηση και 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'}
Απαντήθηκε 01/08/2017 στις 07:14
πηγή χρήστη

ψήφοι
2

Ένα χρήσιμο παράδειγμα που βρήκα μπορεί να είναι χρήσιμες:

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)

Δείγμα εισόδου: 14445221

Δείγμα εξόδου: (1,1) (3,4) (1,5) (2,2) (1,1)

Απαντήθηκε 18/06/2017 στις 17:16
πηγή χρήστη

ψήφοι
1

Μπορείτε να γράψετε τη δική του λειτουργία groupby:

           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]}
Απαντήθηκε 10/10/2018 στις 17:53
πηγή χρήστη

ψήφοι
-1

Κάντε μια iterator που επιστρέφει συνεχόμενες κλειδιά και ομάδες από την iterable. Το κλειδί είναι μια συνάρτηση υπολογίζοντας μια βασική αξία για κάθε στοιχείο.

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
Απαντήθηκε 23/08/2018 στις 06:44
πηγή χρήστη

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