python list-map 형태의 자료에서 같은 value 값끼리 카운트 하는 좋은 코드가 뭐가 있을까요?

조회수 1013회
origin = [
    {'pk':1, 'attr':'MAN'},
    {'pk':1, 'attr':'WOMAN'},
    {'pk':1, 'attr':'BOY'},
    {'pk':1, 'attr':'MAN'},
    {'pk':1, 'attr':'MAN'},
    {'pk':2, 'attr':'MAN'},
]

result = [
    {'pk':1, 'MAN':3, 'WOMAN':1, 'BOY':1},
    {'pk':2, 'MAN':1, 'WOMAN':0, 'BOY':1}
]

origin 변수에 할당 된 리스트-맵 형태의 데이터가 result 변수에 할당 된 모습처럼 attr 키의 값들이 카운트 되어야 합니다. 단, result 변수는 리스트-맵 형태여도 되고 하나의 맵 자료형에서 pk만 구분 되어도 됩니다. pandas나 데이터 프레임을 사용 못하는 환경에서 어떻게하면 좀 더 효과적인 반복문을 사용할 수 있을까요?

3 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    attr 값이 다양하게 나타날 수 있으므로 데이터셋의 모든 attr 항목들을 살펴봐야 합니다.

    origin = [
        {'pk':1, 'attr':'MAN'},
        {'pk':1, 'attr':'WOMAN'},
        {'pk':1, 'attr':'BOY'},
        {'pk':1, 'attr':'MAN'},
        {'pk':1, 'attr':'MAN'},
        {'pk':2, 'attr':'MAN'},
        {'pk':2, 'attr':'BOY'},
        {'pk':2, 'attr':'GIRL'},
    ]
    import itertools as it
    import operator as op
    from collections import Counter
    
    origin_grouped = it.groupby(origin, key=op.itemgetter('pk'))
    origin_count = [{'pk':grouped[0], **dict(Counter([d['attr'] for d in list(grouped[1])]))} for grouped in origin_grouped]
    
    total_keys = dict.fromkeys(set().union(*origin_count), 0)
    [dict(total_keys, **d) for d in origin_count]
    
    [{'WOMAN': 1, 'MAN': 3, 'pk': 1, 'GIRL': 0, 'BOY': 1},
     {'WOMAN': 0, 'MAN': 1, 'pk': 2, 'GIRL': 1, 'BOY': 1}]
    
  • 
    origin = [
        {'pk':1, 'attr':'MAN'},
        {'pk':1, 'attr':'WOMAN'},
        {'pk':1, 'attr':'BOY'},
        {'pk':1, 'attr':'MAN'},
        {'pk':1, 'attr':'MAN'},
        {'pk':2, 'attr':'MAN'},
    ]
    
    counter = dict()
    
    for entry in origin:
        pk = entry['pk']
        attr = entry['attr']
        d = counter.get(pk, dict())
        d[attr] = d.get(attr, 0) + 1
        counter[pk] = d
    
    print(counter)
    
    {1: {'MAN': 3, 'WOMAN': 1, 'BOY': 1}, 
     2: {'MAN': 1}}
    

    아주 원하는 형식은 아니지만, 이런 게 가능합니다.

    • 감사합니다~!!! 김재민 2021.3.8 14:37
  • 무식하게 해결해야 하지 않을까요..

    pk 값이 동일하면 개별 attr값을 가진 dict를 추가하는게 아니라 attr을 리스트로 사용하는게 더 좋을 것 같습니다.

    origin = [
        {'pk':1, 'attr':'MAN'},
        {'pk':1, 'attr':'WOMAN'},
        {'pk':1, 'attr':'BOY'},
        {'pk':1, 'attr':'MAN'},
        {'pk':1, 'attr':'MAN'},
        {'pk':2, 'attr':'MAN'},
    ]
    
    a = []
    b = {}
    for i in origin:
        if i['pk'] not in a:
            a.append(i['pk'])
            b.update({i['pk']:[]})
    print(a)
    print(b)
    
    for i in origin:
        b[i['pk']].append(i['attr'])
    print(b)
    
    
    result = []
    for i in b:
        c = b[i].count('MAN')
        d = b[i].count('WOMAN')
        e = b[i].count('BOY')
        result.append({'pk':i, 'MAN':c, 'WOMAN':d, 'BOY':e})
    print(result)
    
    >>> [{'pk': 1, 'MAN': 3, 'WOMAN': 1, 'BOY': 1}, {'pk': 2, 'MAN': 1, 'WOMAN': 0, 'BOY': 0}]
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)