2014-02-25 2 views
4

기능적이고 반복적 인 도구를 사용하여 긴 데이터 집합을 넓은 것으로 변환하려고합니다.이 점이 groupby의 작업입니다. 내가 전에 이것에 대해 몇 가지 질문을 물어, 내가 그것을했다 생각했지만, 확실히이 경우, 이는 간단한다고했습니다groupby를 사용하여 long-to-wide 파이썬 one-liner (또는 two)를 반복적으로 사용합니다.

가 있어요 데이터 내가 가진 :

,691,363 : 여기
from itertools import groupby 
from operator import itemgetter 
from pprint import pprint 

>>> longdat=[ 
{"id":"cat", "name" : "best meower", "value": 10}, 
{"id":"cat", "name" : "cleanest paws", "value": 8}, 
{"id":"cat", "name" : "fanciest", "value": 9}, 
{"id":"dog", "name" : "smelly", "value": 9}, 
{"id":"dog", "name" : "dumb", "value": 9}, 
] 

의 형식은 내가 그것을 원하는이다 ,

# WRONG 
>>> gh = groupby(sorted(longdat,key=id),itemgetter('id')) 
>>> list(gh) 
[('cat', <itertools._grouper object at 0x5d0b550>), ('dog', <itertools._grouper object at 0x5d0b210>)] 

OK 충분히 공정, 반복자에서 두 번째 항목을 얻을 필요가 : 여기

>>> widedat=[ 
{"id":"cat", "best meower": 10, "cleanest paws": 8, "fanciest": 9}, 
{"id":"dog", "smelly": 9, "dumb": 9}, 
] 

(210) 내 실패한 시도합니다.

#WRONG 
>>> gh = groupby(sorted(longdat,key=id),itemgetter('id')) 
>>> for g,v in gh: 
...  {"id":i["id"], i["name"]:i["value"] for i in v} 
            ^
SyntaxError: invalid syntax 

이상한 것으로 보입니다. 루프를 풀어서 확인하십시오.

#WRONG 
gb = groupby(sorted(longdat,key=id),itemgetter('id')) 
data = {} 
for g,v in gb: 
    data[g] = {} 
    for i in v: 
     data[g] = i 

#WRONG 
gb = groupby(sorted(longdat,key=id),itemgetter('id')) 
data = [] 
for g,v in gb: 
    for i in v: 
     data[g] = i 

Ah! 자, 한 줄 형식으로 돌아 가자.

#WRONG 
>>> gb = groupby(sorted(longdat,key=id),itemgetter('id')) 
>>> [{"id":g, i["name"]:i["value"]} for i in k for g,k in gb] 
[] 

무엇? 왜 비어 있니?! 의는 기본적으로 정확히이 다시 긴장을 풀어 보자

#WRONG 
gb = groupby(sorted(longdat,key=id),itemgetter('id')) 
for g,k in gb: 
    for i in k: 
     print(g, i["name"],i["value"]) 
cat best meower 10 
cat fanciest 9 
cat cleanest paws 8 
dog smelly 9 
dog dumb 9 

지금이 마지막 분명히 최악 --- 시작 어디조차 GROUPBY했던 것처럼 내 데이터는, 바로 돌아 기본적으로 분명하다.

왜이 기능이 작동하지 않으며 내가 원하는 형식으로 어떻게 가져올 수 있습니까?

또한, == 내가

>>> result[0] 
{"id":"cat", "best meower": 10, "cleanest paws": 8, "fanciest": 9} 

을 만 모두/어디 ID/볼 필요 이상으로 (전체 목록을 처리하지 않고 첫 번째 결과를 얻을 수 있다는 문구 가능성이 완전히 반복적으로 같은 그 것이다 '고양이'?)

+1

감사합니다. 이렇게 잘 쓰여진 질문은 요즘의 희소성입니다. – IceArdor

+0

고마워, 아이스 애도.사람들은 보통 불필요하게 길게 만 부릅니다. ;) – Mittenchops

답변

4

key 함수는 함수에 전달됩니다. id입니다. 모든 목록 항목에 대해 다른 값을 모두 반환합니다.

itemgetter('id') 또는 lambda x: x.id이어야합니다.

>>> id(longdat[0]) 
41859624L 
>>> id(longdat[1]) 
41860488L 
>>> id(longdat[2]) 
41860200L 
>>> itemgetter('id')(longdat[1]) 
'cat' 
>>> itemgetter('id')(longdat[2]) 
'cat' 
>>> itemgetter('id')(longdat[3]) 
'cat' 


from itertools import groupby 
from operator import itemgetter 

longdat = [ 
    {"id":"cat", "name" : "best meower", "value": 10}, 
    {"id":"cat", "name" : "cleanest paws", "value": 8}, 
    {"id":"cat", "name" : "fanciest", "value": 9}, 
    {"id":"dog", "name" : "smelly", "value": 9}, 
    {"id":"dog", "name" : "dumb", "value": 9}, 
] 

getid = itemgetter('id') 
result = [ 
    dict([['id', key]] + [[d['name'], d['value']] for d in grp]) 
    for key, grp in groupby(sorted(longdat, key=getid), key=getid) 
] 
print(result) 

출력 : 즉, 예제 문제를 설명하고 연구하고 시도했는지 보여주는

[{'best meower': 10, 'fanciest': 9, 'id': 'cat', 'cleanest paws': 8}, 
{'dumb': 9, 'smelly': 9, 'id': 'dog'}] 
+0

당신의 dict ([[]] + [[])) 구문을'[{ 'id': key, d [ 'name'] : d [ 'value']로 대체하려고 할 때 나는 무엇을 놓치고 있습니까? d는 grp} 키, grp in gb]'dict() 함수보다는 {} 생성자만으로는 안됩니까? – Mittenchops

+0

@Mittenchops, 당신은 독해력을 의미합니까? 나는 [[..]] + [[..]] itertating 또는 itertools.chain ...을 사용하지 않고 dict comprehension을 사용하는 방법을 모른다. – falsetru

+1

@Mittenchops, dict comprehension을 사용하려면 [ 이] (http://ideone.com/To88FA). 좀 더 길다. btw. – falsetru