Как сгруппировать список диктов в подсписки, используя панд? - PullRequest
1 голос
/ 19 июня 2019

вход - это что-то вроде

[
  {"name": "person 1", "age": 20, "type": "student"},
  {"name": "person 2", "age": 19, "type": "worker"},
  {"name": "person 3", "age": 30, "type": "student"},
  {"name": "person 4", "age": 25, "type": "worker"},
  {"name": "person 5", "age": 17, "type": "student"}
]

и желаемый результат при группировании по полю типа должен быть

[
  [
    {"name": "person 1", "age": 20, "type": "student"},
    {"name": "person 3", "age": 30, "type": "student"},    
    {"name": "person 5", "age": 17, "type": "student"}
  ],
  [
    {"name": "person 2", "age": 19, "type": "worker"},
    {"name": "person 4", "age": 25, "type": "worker"}
  ]
]

У меня есть следующий код, чтобы сделать это с itertools

from itertools import groupby

input = [
  {"name": "person 1", "age": 20, "type": "student"},
  {"name": "person 2", "age": 19, "type": "worker"},
  {"name": "person 3", "age": 30, "type": "student"},
  {"name": "person 4", "age": 25, "type": "worker"},
  {"name": "person 5", "age": 17, "type": "student"}
]

input.sort(key=lambda x: x["type"])
output = [list(v) for k, v in groupby(input, key=lambda x: x["type"])]

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

import pandas as pd

input = [
  {"name": "person 1", "age": 20, "type": "student"},
  {"name": "person 2", "age": 19, "type": "worker"},
  {"name": "person 3", "age": 30, "type": "student"},
  {"name": "person 4", "age": 25, "type": "worker"},
  {"name": "person 5", "age": 17, "type": "student"}
]

indexes = [list(v) for k, v in pd.DataFrame(input).groupby(["type"]).groups.items()]
output = [[input[y] for y in x] for x in indexes]

Я почти уверен, что приведенный выше код - очень неправильный способ использования функциональности pandas groupby, поэтому какая-нибудь помощь в том, как сделать это правильно? Спасибо.

Ответы [ 2 ]

2 голосов
/ 19 июня 2019

Вы можете сделать это с GroupBy.apply и to_dict:

pd.DataFrame(input).groupby('type').apply(lambda x: x.to_dict('r')).to_list()

Чуть быстрее,

pd.DataFrame(input).groupby('type').apply(
    pd.DataFrame.to_dict, orient='r').tolist()

# [[{'age': 20, 'name': 'person 1', 'type': 'student'},
#   {'age': 30, 'name': 'person 3', 'type': 'student'},
#   {'age': 17, 'name': 'person 5', 'type': 'student'}],
#  [{'age': 19, 'name': 'person 2', 'type': 'worker'},
#   {'age': 25, 'name': 'person 4', 'type': 'worker'}]]
1 голос
/ 19 июня 2019

Что я буду делать

l1=[[y.iloc[0].to_dict() for  z in y.iterrows()] for _ , y in pd.DataFrame(input).groupby('type')]
Out[254]: 
[[{'age': 20, 'name': 'person 1', 'type': 'student'},
  {'age': 20, 'name': 'person 1', 'type': 'student'},
  {'age': 20, 'name': 'person 1', 'type': 'student'}],
 [{'age': 19, 'name': 'person 2', 'type': 'worker'},
  {'age': 19, 'name': 'person 2', 'type': 'worker'}]]

А также, если нужно только сопоставить ключ со значением, вы можете проверить с помощью itertuples

l=[list(y.itertuples()) for _ , y in pd.DataFrame(input).groupby('type')]
Out[256]: 
[[Pandas(Index=0, age=20, name='person 1', type='student'),
  Pandas(Index=2, age=30, name='person 3', type='student'),
  Pandas(Index=4, age=17, name='person 5', type='student')],
 [Pandas(Index=1, age=19, name='person 2', type='worker'),
  Pandas(Index=3, age=25, name='person 4', type='worker')]]

Сравнить

l[0][0].age
Out[263]: 20
l1[0][0]['age']
Out[264]: 20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...