объединить общие элементы списка словаря и сохранить необычные элементы в новом ключе

#python #pandas

#питон #панды

Вопрос:

У меня очень большой словарь с ключами, содержащими список элементов, они неупорядочены. Я хотел бы сгруппировать определенные элементы в новом ключе. Например

input= [{'name':'emp1','state':'TX','areacode':'001','mobile':123},{'name':'emp1','state':'TX','areacode':'002','mobile':234},{'name':'emp1','state':'TX','areacode':'003','mobile':345},{'name':'emp2','state':'TX','areacode':None,'mobile':None},]

для приведенных выше входных данных я хотел бы сгруппировать areacode и mobile в новом ключе contactoptions

 opdata = [{'name':'emp1','state':'TX','contactoptions':[{'areacode':'001','mobile':123},{'areacode':'002','mobile':234},{'areacode':'003','mobile':345}]},{'name':'emp2','state':'TX','contactoptions':[{'areacode':None,'mobile':None}]}]
 

я делаю это сейчас с помощью двух длинных итераций. я хотел добиться того же более эффективно, так как количество записей велико. открыт для использования существующих методов, если они доступны в таких пакетах, как pandas.

Ответ №1:

Попробуйте

 result = (
    df.groupby(['name', 'state'])
      .apply(lambda x: x[['areacode', 'mobile']].to_dict(orient='records'))
      .reset_index(name='contactoptions')
    ).to_dict(orient='records')
 

Ответ №2:

С обычными словарями вы можете сделать это за один проход / цикл, используя метод setdefault и не сортируя:

 data = [{'name':'emp1','state':'TX','areacode':'001','mobile':123},{'name':'emp1','state':'TX','areacode':'002','mobile':234},{'name':'emp1','state':'TX','areacode':'003','mobile':345},{'name':'emp2','state':'TX','areacode':None,'mobile':None}]

merged = dict()
for d in data:
    od = merged.setdefault(d["name"],{k:d[k] for k in ("name","state")})
    od.setdefault("contactoptions",[]).append({k:d[k] for k in ("areacode","mobile")})
merged = list(merged.values())
 

выходной сигнал:

 print(merged)
# [{'name': 'emp1', 'state': 'TX', 'contactoptions': [{'areacode': '001', 'mobile': 123}, {'areacode': '002', 'mobile': 234}, {'areacode': '003', 'mobile': 345}]}, {'name': 'emp2', 'state': 'TX', 'contactoptions': [{'areacode': None, 'mobile': None}]}]
 

Ответ №3:

Как вы и просили, вы хотите сгруппировать входные элементы по «имени» и «состоянию» вместе.

Мое предложение заключается в том, что вы можете создать словарь, ключами которого будут «имя» плюс «состояние», например, 'emp1-TX' а значениями будут список «areacode» и «mobile», например [{'areacode':'001','mobile':123}] . В этом случае результат может быть достигнут за одну итерацию.

Вывод:

 {'emp1-TX': [{'areacode':'001','mobile':123}, {'areacode':'001','mobile':123}, {'areacode':'003','mobile':345}], 'emp2-TX': [{'areacode':None,'mobile':None}]}