Используя панд, чтобы сложить список диктов вместе - PullRequest
0 голосов
/ 09 мая 2018

Это продолжение этого вопроса: Использование панд для добавления элементов списка вместе . Я хотел бы обобщить эту функцию для получения уникальных элементов в массиве, даже если они не относятся к типу «hashable», например, dict. Вот входной массив:

items = [ 
{
    'FirstName': 'David',
    'LastName': 'Smith',
    'Residence': [{'Place': 'X', 'Age': 22}, {'Place': 'Y', 'Age': 23}]
},

{
    'FirstName': 'David',
    'LastName': 'Smith',
    'Residence': [{'Place': 'Z', 'Age': 20}]
},

{
    'FirstName': 'David',
    'LastName': 'Smith',
    'Residence': [{'Place': 'Z', 'Age': 20}]
},
{
    'FirstName': 'Bob',
    'LastName': 'Jones',
    'Residence': [{'Place': 'Z', 'Age': 20}]
}
]

Я хочу сложить вместе уникальные Резиденции (дикты), поэтому конечный результат будет:

items = [ 
{
    'FirstName': 'David',
    'LastName': 'Smith',
    'Residence': [{'Place': 'X', 'Age': 22}, {'Place': 'Y', 'Age': 23}, {'Place': 'Z', 'Age': 20}]
},

{
    'FirstName': 'Bob',
    'LastName': 'Jones',
    'Residence': [{'Place': 'Z', 'Age': 20}]
}
]

SQL-код, который я бы использовал, был бы примерно таким:

SELECT FirstName, LastName, GROUP_CONCAT(DISTINCT **Residence Object**)
FROM items
GROUP BY FirstName, LastName

Как бы я сделал это в pandas, чтобы я не получил ошибку unhashable type при попытке получить отдельные элементы массива?

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Раствор от pandas

#df=pd.DataFrame(items)
df.groupby(['FirstName','LastName']).Residence.\
    apply(lambda x : x.sum()).\
       apply(lambda x : [dict(y) for y in set(tuple(t.items()) for t in x)]).\
         reset_index().to_dict('r')
Out[104]: 
[{'FirstName': 'Bob',
  'LastName': 'Jones',
  'Residence': [{'Age': 20, 'Place': 'Z'}]},
 {'FirstName': 'David',
  'LastName': 'Smith',
  'Residence': [{'Age': 20, 'Place': 'Z'},
   {'Age': 23, 'Place': 'Y'},
   {'Age': 22, 'Place': 'X'}]}]
0 голосов
/ 09 мая 2018

Вы можете сделать

df.groupby(["FirstName", "LastName"])["Residence"].apply(sum)\
.apply(lambda x: [i for n, i in enumerate(x) if i not in d[n + 1:]]).reset_index()\
.to_dict(orient='r')

[{'FirstName': 'Bob',
  'LastName': 'Jones',
  'Residence': [{'Place': 'Z', 'Age': 20}]},
 {'FirstName': 'David',
  'LastName': 'Smith',
  'Residence': [{'Place': 'X', 'Age': 22},
   {'Place': 'Y', 'Age': 23},
   {'Place': 'Z', 'Age': 20}]}]
0 голосов
/ 09 мая 2018

Если не считать чего-либо еще, я не думаю, что Панды принесут вам какую-то реальную выгоду:

from collections import defaultdict

d = defaultdict(list)
for e in items:
    d[(e['FirstName'], e['LastName'])].append(e['Residence'])
items = [{'FirstName': k[0], 'LastName': k[1], 'Residence': v} for k, v in d.items()]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...