Splitting dict by value of one of the keys

后端 未结 4 815
隐瞒了意图╮
隐瞒了意图╮ 2020-12-19 19:45

I\'ve got a dictionary with data of the same length (but different types), something like:

data = {
    \"id\": [1,1,2,2,1,2,1,2], 
    \"info\": [\"info1\",         


        
相关标签:
4条回答
  • 2020-12-19 20:12

    For working with records, I personally like numpy.recarray.

    In [3]: import numpy as np
    In [4]: fields = data.keys()
    In [8]: recs = zip(*[ lst for k, lst in data.iteritems() ])
    
    In [9]: recs[0]
    Out[9]: ('info1', 1, 1)
    In [10]: recs[1]
    Out[10]: ('info2', 1, 2)
    
    In [21]: ra = np.rec.fromrecords(recs, names = fields )
    In [17]: ra
    rec.array([('info1', 1, 1), ('info2', 1, 2), ('info3', 2, 3), ('info4', 2, 4),
           ('info5', 1, 5), ('info6', 2, 6), ('info7', 1, 7), ('info8', 2, 8)], 
          dtype=[('info', 'S5'), ('id', '<i8'), ('number', '<i8')])
    
    In [23]: ra[ra.id == 2]
    rec.array([('info3', 2, 3), ('info4', 2, 4), ('info6', 2, 6), ('info8', 2, 8)], 
          dtype=[('info', 'S5'), ('id', '<i8'), ('number', '<i8')])
    
    In [24]: ra[ra.id == 2].number
    Out[24]: array([3, 4, 6, 8])
    
    In [25]: ra[ra.id == 2][0]
    Out[25]: ('info3', 2, 3)
    
    In [26]: ra[ra.id == 2][0].number
    Out[26]: 3
    

    If you want to group the records by id in a dict, do:

    { id: ra[ra.id == id] for id in set(ra.id) }
    
    0 讨论(0)
  • 2020-12-19 20:12
    >>> from collections import defaultdict
    >>> res = defaultdict(list)
    >>> for ID,info in zip(data["id"],data["info"]):
        res[ID].append(info)
    
    
    >>> res
    defaultdict(<type 'list'>, {1: ['info1', 'info2', 'info5', 'info7'], 2: ['info3', 'info4', 'info6', 'info8']})
    >>> 
    
    0 讨论(0)
  • 2020-12-19 20:13
    from collections import defaultdict
    
    ids = data.pop('id')
    databyid = defaultdict(lambda: defaultdict(list))
    
    for id, values in zip(ids, zip(*data.values())):
        for kid, kval in enumerate(data.keys()):
            databyid[id][kval].append(values[kid])
    

    if you need data in original state (with id):

     data['id'] = ids
    

    result:

    >>> databyid[1]
    defaultdict(<type 'list'>, {'info': ['info1', 'info2', 'info5', 'info7'], 'number': [1, 2, 5, 7]})
    >>> databyid[2]
    defaultdict(<type 'list'>, {'info': ['info3', 'info4', 'info6', 'info8'], 'number': [3, 4, 6, 8]})
    >>> 
    
    0 讨论(0)
  • 2020-12-19 20:26

    with comprehension lists :

    data1 = [ data["info"][idx] for idx, x in enumerate(data["id"]) if x == 1 ]
    #data1 = ['info1', 'info2', 'info5', 'info7']
    

    If you want to recover all the keys :

    data1 = [ { key : data[key][idx] for key in data.keys() }  for idx, x in enu
    merate(data["id"]) if x == 1 ]
    >>> data1
    [{'info': 'info1', 'id': 1, 'number': 1}, {'info': 'info2', 'id': 1, 'number': 2
    }, {'info': 'info5', 'id': 1, 'number': 5}, {'info': 'info7', 'id': 1, 'number':
     7}]
    
    0 讨论(0)
提交回复
热议问题