Python의 itertools.groupby()를 어떻게 사용합니까?
문제
Python을 실제로 사용하는 방법에 대한 이해 가능한 설명을 찾지 못했습니다. itertools.groupby()
기능.내가하려는 것은 이것이다 :
- 목록을 작성하십시오 - 이 경우에는 객관화된 자녀의 자녀입니다.
lxml
요소 - 몇 가지 기준에 따라 그룹으로 나눕니다.
- 그런 다음 나중에 각 그룹을 개별적으로 반복합니다.
나는 검토했다 문서, 그리고 예, 그러나 단순한 숫자 목록 이상으로 적용하는 데 어려움을 겪었습니다.
그럼 어떻게 사용하나요? itertools.groupby()
?사용해야 하는 또 다른 기술이 있나요?좋은 "전제 조건" 읽기에 대한 조언도 감사하겠습니다.
해결책
중요 사항: 당신은해야 데이터 정렬 첫 번째.
내가 얻지 못한 부분은 예제 구성에서
groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
groups.append(list(g)) # Store group iterator as a list
uniquekeys.append(k)
k
현재 그룹화 키입니다. g
해당 그룹화 키로 정의된 그룹을 반복하는 데 사용할 수 있는 반복자입니다.즉, groupby
반복자 자체는 반복자를 반환합니다.
다음은 더 명확한 변수 이름을 사용하는 예입니다.
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
각 고유 키에 대해 한 번씩 세 개의(키, 그룹 반복자) 쌍을 반환합니다.반환된 반복자를 사용하여 해당 그룹의 각 개별 항목을 반복할 수 있습니다.
다음은 목록 이해를 사용하여 동일한 데이터를 사용한 약간 다른 예입니다.
for key, group in groupby(things, lambda x: x[0]):
listOfThings = " and ".join([thing[1] for thing in group])
print key + "s: " + listOfThings + "."
결과는 다음과 같습니다.
동물:곰과 오리.
식물:선인장.
차량:스피드보트와 스쿨버스.
다른 팁
코드를 보여주실 수 있나요?
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
메서드는 실제로 목록을 반복하고 키가 변경될 때마다 새 그룹을 만듭니다.
groupby의 깔끔한 트릭은 길이 인코딩을 한 줄로 실행하는 것입니다.
[(c,len(list(cgen))) for c,cgen in groupby(some_string)]
첫 번째 요소는 문자이고 두 번째 요소는 반복 횟수인 2-튜플 목록을 제공합니다.
편집하다:이렇게 구분이 되니 참고하세요 itertools.groupby
SQL에서 GROUP BY
의미론:itertools는 반복자를 미리 정렬하지 않으며 일반적으로 정렬할 수 없으므로 동일한 "키"를 가진 그룹은 병합되지 않습니다.
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
객체는 그룹이 생성자인 키-그룹 쌍을 생성합니다.
특징
- ㅏ.연속된 항목을 그룹화
- 비.정렬된 반복 가능 항목이 주어지면 항목의 모든 항목을 그룹화합니다.
- 씨.주요 기능을 사용하여 항목을 그룹화하는 방법 지정
비교
# 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 function
>>> 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']
용도
- 철자 바꾸기 (노트북을 참조하세요)
- 비닝
- 그룹 홀수와 짝수
- 값별로 목록 그룹화
- 중복 요소 제거
- 배열에서 반복되는 요소의 인덱스 찾기
- 배열을 n 크기의 청크로 분할
- 두 목록 사이에서 해당 요소 찾기
- 압축 알고리즘 (노트북을 참조하세요)/길이 인코딩 실행
- 길이, 키 기능별로 문자 그룹화 (노트북을 참조하세요)
- 임계값을 초과하는 연속 값 (노트북을 참조하세요)
- 목록에서 숫자 범위 찾기 또는 연속 항목 (보다 문서)
- 관련된 가장 긴 시퀀스를 모두 찾습니다.
- 조건을 충족하는 연속 시퀀스 가져오기 (관련 포스팅 보러가기)
메모:후자의 예 중 일부는 Víctor Terrón의 PyCon에서 파생되었습니다. (말하다) (스페인의), "Itertools를 사용한 새벽의 쿵푸".또한 참조하십시오 groupby
소스 코드 C로 작성되었습니다.
응답
# OP: Yes, you can use `groupby`, e.g.
[do_something(list(g)) for _, g in groupby(lxml_elements, key=criteria_func)]
다른 예시:
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은 반복자(문서에서는 하위 반복자라고 함)입니다.
이는 생성기를 청크하는 데 유용합니다.
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의 값으로 그룹화됩니다.이 경우 0 세트 하나가 먼저 출력되고, 1 세트가 출력되고, 0 세트가 다시 출력됩니다.
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]
경고:
list(groupby(...)) 구문은 의도한 대로 작동하지 않습니다.내부 반복자 객체를 파괴하는 것 같으므로 다음을 사용하십시오.
for x in list(groupby(range(10))):
print(list(x[1]))
생산할 것입니다:
[]
[]
[]
[]
[]
[]
[]
[]
[]
[9]
대신 list(groupby(...)) 대신 [(k, list(g)) for k,g in groupby(...)]를 시도하거나 해당 구문을 자주 사용하는 경우
def groupbylist(*args, **kwargs):
return [(k, list(g)) for k, g in groupby(*args, **kwargs)]
성가신(작은 데이터의 경우) 반복자를 모두 피하면서 그룹별 기능에 액세스할 수 있습니다.
정렬 없이 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.
차량이 있는 두 그룹이 있는 반면, 하나의 그룹만 기대할 수 있습니다.
@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와 두 개의 e가 있지만 서로 다른 그룹으로 나뉘어져 있습니다.그때 나는 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 함수를 기억하세요. 작동 안 할 것이다!
Python의 itertools.groupby()를 어떻게 사용합니까?
groupby를 사용하여 반복할 항목을 그룹화할 수 있습니다.groupby에 반복 가능 및 선택 사항을 제공합니다. 열쇠 iterable에서 나오는 항목을 확인하는 함수/콜러블이며, 키 콜러블의 결과와 다른 iterable의 실제 항목의 2튜플을 제공하는 반복자를 반환합니다.도움말에서:
groupby(iterable[, keyfunc]) -> create an iterator which returns
(key, sub-iterator) grouped by each value of key(value).
다음은 개수별로 그룹화하기 위해 코루틴을 사용하는 groupby의 예입니다. 호출 가능한 키를 사용합니다(이 경우 coroutine.send
) 얼마나 많은 반복 횟수와 요소의 그룹화된 하위 반복기에 대한 수를 뱉어냅니다.
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])]
정렬 및 그룹화
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'}
제가 본 한 가지 유용한 예가 도움이 될 수 있습니다.
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)
자신만의 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]}