Агрегировать по значению в списке

Как я могу сгруппировать значения, представленные в el1, по первому элементу подсписка, которым является Германия, как показано ниже.

Вход

from collections import defaultdict

el = [('GPE', 'Germany', 10, 12, 1.0), ('GPE', 'Germany', 23, 25, 1.0), ('GPE', 'Germany', 81, 83, 1.0),
 ('GPE', 'Germany', 163, 165, 1.0), ('GPE', 'Brazil', 219, 221, 1.0), ('GPE', 'Brazil', 260, 262, 1.0),
 ('CARDINAL', 'at least 3000', 26, 29, 1.0), ('CARDINAL', '124', 94, 95, 1.0)]


el1 = defaultdict(list)

for en,c,s,e,sf in el:
    el1[en].append((c,(s,e,sf)))

el1.items()

el1.items()

dict_items([('GPE', [('Germany', (10, 12, 1.0)), ('Germany', (23, 25, 1.0)), ('Germany', (81, 83, 1.0)), ('Germany', (163, 165, 1.0)), ('Brazil', (219, 221, 1.0)), ('Brazil', (260, 262, 1.0))]), ('CARDINAL', [('at least 3000', (26, 29, 1.0)), ('124', (94, 95, 1.0))])])

Код, который я пробовал для группировки

import itertools
key_func = lambda x: x[0]

for i in list(el1.items()):
    for j in i[1]:    
        for key, group in itertools.groupby(j, key_func):
            print(key, list(group))

выход

G ['Germany']
10 [(10, 12, 1.0)]
G ['Germany']
23 [(23, 25, 1.0)]
G ['Germany']
81 [(81, 83, 1.0)]
G ['Germany']

Ожидаемый результат

 [('GPE', [('Germany', [(10, 12, 1.0), (23, 25, 1.0), (81, 83, 1.0), (163, 165, 1.0)]),
          ('Brazil', [(219, 221, 1.0), (260, 262, 1.0)])]), 
 ('CARDINAL', [('at least 3000', [(26, 29, 1.0)]), 
               ('124', [(94, 95, 1.0)])])]

Не могли бы вы показать, что вы пробовали. а что не так?

Daniel Hao 13.12.2020 05:05

@DanielHao Я добавил код и промежуточные результаты

joel 13.12.2020 06:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
83
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Теперь эта проблема более ясна. Вот метод, использующий panda dataframe.groupby():

d = defaultdict(list)
for k,v in pd.DataFrame(el, columns = ['t','c','v1','v2','v3']).groupby(['t','c']):
    d[k[0]].append((k[1], [tuple(arr[2:]) for arr in v.to_dict(orient='split')['data']]))

Выход

defaultdict(list,
        {'CARDINAL': [('124', [(94, 95, 1.0)]),
          ('at least 3000', [(26, 29, 1.0)])],
         'GPE': [('Brazil', [(219, 221, 1.0), (260, 262, 1.0)]),
          ('Germany',
           [(10, 12, 1.0),
            (23, 25, 1.0),
            (81, 83, 1.0),
            (163, 165, 1.0)])]})

СТАРЫЙ ОТВЕТ

from collections import defaultdict
d = defaultdict(list) 
d['GPE'].append(dict(text = 'Germany', offset = [(10, 12, 1.0),
                                                 (23, 25, 1.0),
                                                 (81, 83, 1.0),
                                                 (163, 165, 1.0)
                                                ]))
d['GPE'].append(dict(text = 'Brazil', offset = [(219, 221, 1.0),
                                                (260, 262, 1.0)
                                               ]))

d['CARDINAL'].append(dict(text = 'at least 3000', offset = [(26, 29, 1.0)]))
d['CARDINAL'].append(dict(text = '124', offset = [(94, 95, 1.0)]))
print(d)

Извините за путаницу. Я добавил код и промежуточные результаты.

joel 13.12.2020 06:25

Добавлен пример с использованием pandas groupby().

frankr6591 14.12.2020 01:13
from itertools import groupby
from collections import defaultdict
from pprint import pprint

el = [...same elements...]

d = defaultdict(list)
e = defaultdict(list)

for k, v in groupby(el, key=lambda x: x[0]):
    for x, y, *z in v:
        e[y].append(tuple(z))   
    
    for g, h in e.items():
        d[k].append((g, h))

    e = defaultdict(list)

g = dict(d)

print(g.items(),'\n')
pprint(g, width=100, sort_dicts=False)
dict_items([('GPE', [('Germany', [(10, 12, 1.0), (23, 25, 1.0), (81, 83, 1.0), (163, 165, 1.0)]), ('Brazil', [(219, 221, 1.0), (260, 262, 1.0)])]), ('CARDINAL', [('at least 3000', [(26, 29, 1.0)]), ('124', [(94, 95, 1.0)])])])

{'GPE': [('Germany', [(10, 12, 1.0), (23, 25, 1.0), (81, 83, 1.0), (163, 165, 1.0)]),
         ('Brazil', [(219, 221, 1.0), (260, 262, 1.0)])],
 'CARDINAL': [('at least 3000', [(26, 29, 1.0)]), ('124', [(94, 95, 1.0)])]}

Это ответило на вопрос.

Daniel Hao 13.12.2020 16:31

Другие вопросы по теме