Nasıl Python'un itertools.groupby () kullanıyorsunuz?

oy
364

Aslında Python'un nasıl kullanılacağına dair anlaşılabilir bir açıklama bulmak mümkün olmamıştır itertools.groupby()işlevi. Ne yapmaya çalışıyorum şudur:

  • Bir liste al - bu durumda, nesnelleştirilmiş çocukları lxmlelemanı
  • Bazı ölçütlere göre gruplara bölmek
  • Ardından daha sonra ayrı ayrı bu grupların her üzerinde yineleme.

Ben inceledim belgeleri ve örnekler ; ama sıkıntı numaraları basit listesinin ötesinde bunları uygulamak için çalışıyoruz yaşadım.

Yani, nasıl bir kullanırım itertools.groupby()? Ben kullanarak olmalıdır başka bir teknik var mı? İyi önkoşul okuma işaretçileri de mutluluk duyacağız.

Oluştur 03/08/2008 saat 19:27
kaynak kullanıcı
Diğer dillerde...                            


13 cevaplar

oy
523

Sebastjan dediği gibi, öncelikle verileri sıralamak gerekir. Bu önemli.

Ben alamadım parçası olduğu örnek yapımında

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

kGeçerli gruplama anahtardır ve gbu gruplama tuşu ile tanımlanan grup üzerinde yineleme için kullanabileceğiniz Yineleyicinin. Başka bir deyişle, groupbyyineleyici kendisi yineleyiciler döndürür.

İşte daha net değişken adları kullanarak bu bir örnek verilmiştir:

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

Bu, çıktıyı verecektir:

Bir ayı bir hayvandır.
Ördek bir hayvandır.

Bir kaktüs bir bitkidir.

Bir sürat teknesi bir araçtır.
Bir okul otobüsü bir araçtır.

Bu örnekte, thingsher bir demet içinde Birinci öğe öğenin ait bir gruptur dizilerini listesidir.

groupby()Ile gruplandırmak için grubu ve (2) fonksiyonu (1) veri: işlev iki değer alır.

Burada lambda x: x[0]söyler groupby()gruplama anahtarı olarak her demet ilk madde kullanmak.

Yukarıda foraçıklamada, groupbyüç (anahtar, grup yineleyici) çiftleri döndürür - kez her eşsiz anahtar için. Sen o gruptaki her bir öğesi üzerinde yineleme döndü yineleyici kullanabilirsiniz.

İşte liste kavrayışa sahip olma, aynı verilerle biraz farklı bir örnek:

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

Bu, çıktıyı verecektir:

hayvanlar: Ayı ve ördek.
bitkiler: kaktüs.
araçlar: sürat teknesi ve okul otobüsü.

Cevap 10/08/2008 saat 19:45
kaynak kullanıcı

oy
65

Bize kodunu gösterir misin?

Python dokümanlar üzerinde örnek oldukça basittir:

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

Yani senin durumunda, veri düğümlerinin listesi olan kriterler fonksiyonunun mantık gider ve o zaman nerede, keyfunc olan groupby()verileri grupları.

Sen için dikkatli olmak gerekir verileri sıralamak aramadan önce kriterlere göre groupbyya da çalışmaz. groupbyyöntem aslında sadece bir listesini yineler ve her anahtar değişiklikler yeni bir grup oluşturur.

Cevap 03/08/2008 saat 19:40
kaynak kullanıcı

oy
32

GroupBy ile neato trick bir satır içinde uzunluk şifreleme çalıştırmaktır:

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

İlk eleman Char ve 2 tekrarlar sayısıdır size 2-tüp listeleriniz verecektir.

Düzenleme: Bu ayıran olduğunu unutmayın itertools.groupbySQL gelen GROUP BYsemantik: itertools olmuyorsa (ve olamaz genelde) önceden yineleyici sıralamak aynı "anahtar" birleştirilmez gruplar böylece.

Cevap 01/09/2008 saat 00:27
kaynak kullanıcı

oy
21

Başka bir örnek:

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

sonuçları

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

bu igroup bir yineleyici (belgeleme olarak adlandırdığı bir alt yineleyici) olduğuna dikkat edin.

Bu bir jeneratör chunking için yararlıdır:

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 bir başka örneği - tuşları sıralanır. Aşağıdaki örnekte, xx öğeler yy değerlere göre gruplandırılır. Bu durumda, sıfır bir set çıkışı ilk olanlardan bir dizi izledi, sıfır kümesi tarafından tekrar izledi olduğunu.

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

üretir:

0 [0, 1, 2]
1 [3, 4, 5]
0 [6, 7, 8, 9]
Cevap 21/01/2013 saat 17:54
kaynak kullanıcı

oy
17

UYARI:

sözdizimi listesi (GroupBy (...)) sen amaçladığınız şekilde çalışmayacaktır. O kadar kullanarak, iç yineleyici nesneleri yok gibi görünüyor

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

üretecek:

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

Bunun yerine, listenin (GroupBy (...)), denemek [GroupBy içinde k (k, liste (g)), g (...)] veya sık sözdizimi kullanırsanız,

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

(Küçük veriler için) sinir bozucu olanlar kaçınırken ve hep birlikte yineleyicinızı GroupBy işlevselliğine erişim sağlayabilirsiniz.

Cevap 16/11/2013 saat 01:39
kaynak kullanıcı

oy
11

itertools.groupby öğeleri gruplandırmak için bir araçtır.

Gönderen docs , daha ayrıntılı o ne yapabilir toplamaktadır:

# [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 nesneler grubu, bir jeneratör anahtar grubu çiftlerini verir.

Özellikler

  • A. Grup araya ürün ardışık (benzer unique_justseentarifi)
  • Sıralanmış iterable verilen B. Grubu bir öğenin tüm oluşumları,
  • C. kilit fonksiyonu ile nasıl grup öğeleri belirtin

Karşılaştırmalar

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

Kullanımları

Ikincisi örneklerin birkaçı Víctor Terron en PyCon konuşma türetilen (İngilizce) (İspanyolca) , Itertools ile at Dawn Kung Fu . Ilgilenen herkes için, burada kaynak kodu için groupbyC ile yazılmış

Cevap 25/08/2017 saat 02:26
kaynak kullanıcı

oy
10

Ben türlü olmadan GroupBy çalışmıyor başka bir örnek vermek istiyorum. James Sulak tarafından örnekten uyarlanan

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

çıkışı

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.

vehicule ile iki grup tek tek grup bekliyor olabilir oysa vardır

Cevap 07/05/2013 saat 21:09
kaynak kullanıcı

oy
7

@CaptSolo, senin örnek denedim ama işe yaramadı.

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

Çıktı:

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

Gördüğünüz gibi, orada iki o en ve iki e en, ancak ayrı gruplar girdi. Ben GroupBy işlevine aktarılan listesini sıralamak gerekir o zaman anladım. Yani, doğru kullanım olacaktır:

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

Çıktı:

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

Hatırlayarak Sadece listenin sıralanma değilse, GroupBy işlevi çalışmaz !

Cevap 15/10/2009 saat 16:41
kaynak kullanıcı

oy
5

Nasıl Python'un itertools.groupby () kullanıyorsunuz?

Sen yineleme yapmak için grup şeyler GroupBy kullanabilirsiniz. Sen bir iterable GroupBy vermek ve bir isteğe bağlı anahtar onlar iterable çıkması olarak tarafından çağrılabilir işlev / öğeleri kontrol etmek ve anahtar çağrılabilir ve gerçek öğeler arasında sonucunun iki tuple veren bir yineleyici döndürür başka iterable. Yardım Gönderen:

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

İşte sayımı ile gruba bir eşyordam kullanarak GroupBy bir örnek, kullandığı anahtar çağrılabilir (bu durumda, coroutine.send) sadece bununla birçok tekrarlamalar sayısını ve elementlerin bir gruplandırılmış alt yineleyici tükürmek için:

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

baskılar

[(0, [0, 1, 2]), (1, [3, 4, 5]), (2, [6, 7, 8]), (3, [9])]
Cevap 27/07/2015 saat 18:06
kaynak kullanıcı

oy
3

Sıralama ve 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'}
Cevap 01/08/2017 saat 07:14
kaynak kullanıcı

oy
2

Ben yararlı olabilir rastladı yararlı bir örnek:

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)

Numune girişi: 14445221

Örnek çıktı: (1,1) (3,4) (1,5) (2,2) (1,1)

Cevap 18/06/2017 saat 17:16
kaynak kullanıcı

oy
1

Sen kendi GroupBy fonksiyon yazabiliriz:

           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]}
Cevap 10/10/2018 saat 17:53
kaynak kullanıcı

oy
-1

iterable gelen ardışık anahtarları ve grupları döndüren bir yineleyici olun. anahtar, her elemanı için bir anahtar değeri hesaplama fonksiyonudur.

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
Cevap 23/08/2018 saat 06:44
kaynak kullanıcı

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