Режим объединения, сортировки и получения групп на кортеже - PullRequest
0 голосов
/ 16 октября 2018

У меня есть следующая проблема с ограничением, что у меня нет доступа к import pandas или чему-либо, кроме стандартных библиотек.

Словарь с ID-type1: метка.

{'ID1': 'Label1',
 'ID2': 'Label2',
 'ID3': 'Label2',
 'ID3': 'Label3',
 'ID4': 'Label1',
 'ID5': 'Label4'...}

Список из 3-х кортежей с ID-type1, ID-type2, Val.Каждый идентификатор имеет тысячи уникальных значений.

[('ID1', 'ID_Type2_1', 0.3695652173913043),
 ('ID1', 'ID_Type2_2', 0.35714285714285715),
 ('ID1', 'ID_Type2_3', 0.4146341463414634),
 ('ID2', 'ID_Type2_1', 0.3125),
 ('ID2', 'ID_Type2_2', 0.4418604651162791),
 ('ID2', 'ID_Type2_3', 0.34285714285714286),
 ('ID3', 'ID_Type2_5', 0.35714285714285715),
 ('ID3', 'ID_Type2_3', 0.3488372093023256),
 ('ID3', 'ID_Type2_2', 0.3958333333333333)...]

Если бы словарь представлял собой фрейм данных с именем A (3 столбца), а список - фрейм данных с именем B (2 столбца).Я хотел бы сделать следующую псевдологию.

Прикрепить метку к списку кортежей.

C = left_join(A, B, on =ID-type1)

Затем выберите режим (метку) для каждого ID-type2 среди строк, соответствующих верхним значениям m в столбце Val, или другими словами, сгруппировать по ID-type-2, затем сохранить только верхние m (целые) строки на основе столбца Val, затем выберитеmode / наиболее распространенное значение столбца label.

C.groupby(ID_type-2).arrange(Val).select(rank = n()).filter(rank <= m).select(mode(label))

Другими словами, желаемым выводом является список кортежей с (ID-type2, Label)

редактировать: я думаю, что первый шаг может быть сделан с чем-то вроде этого?Но вторым шагом является сложная часть

from collections import defaultdict
dd = defaultdict(list)
for d in (d1, labels): # you can list as many input dicts as you want here
    # d.iteritems() in 2.0
    for key, value in d.items():
        dd[key].append(value)

1 Ответ

0 голосов
/ 16 октября 2018

Я думаю, что вы можете сделать это с itertools.groupby и модулем statistics.Рассмотрим следующие примеры данных, которые вы разместили в своем вопросе:

import itertools
import statistics

d = {'ID1': 'Label1',
     'ID2': 'Label2',
     'ID3': 'Label2',
     'ID3': 'Label3',
     'ID4': 'Label1',
     'ID5': 'Label4'}

tups = [('ID1', 'ID_Type2_1', 0.3695652173913043),
        ('ID1', 'ID_Type2_2', 0.35714285714285715),
        ('ID1', 'ID_Type2_3', 0.4146341463414634),
        ('ID2', 'ID_Type2_1', 0.3125),
        ('ID2', 'ID_Type2_2', 0.4418604651162791),
        ('ID2', 'ID_Type2_3', 0.34285714285714286),
        ('ID3', 'ID_Type2_5', 0.35714285714285715),
        ('ID3', 'ID_Type2_3', 0.3488372093023256),
        ('ID3', 'ID_Type2_2', 0.3958333333333333),
        ('ID2', 'ID_Type2_5', 0.4958333333333333)]

Вы можете создать «объединение» с простым пониманием списка:

res = [(idt2, idt1, d[idt1], val) for idt1, idt2, val in tups]

Теперь вы можете создавать свои группыс itertools.groupby.Здесь я храню сгруппированные результаты в другом словаре:

res.sort() # groupby expects the list to be sorted by the grouping key

# group by id type 2 and store those grouped lists sorted in descending order of Val
groups = {k: sorted(list(g), key=lambda x: x[-1], reverse=True) for k, g in itertools.groupby(res, key=lambda x: x[0])}

Для приведенных выше примеров данных группы выглядят так:

[('ID_Type2_3', 'ID1', 'Label1', 0.4146341463414634), ('ID_Type2_3', 'ID3', 'Label3', 0.3488372093023256), ('ID_Type2_3', 'ID2', 'Label2', 0.34285714285714286)]                   
[('ID_Type2_1', 'ID1', 'Label1', 0.3695652173913043), ('ID_Type2_1', 'ID2', 'Label2', 0.3125)]                                                                                     
[('ID_Type2_2', 'ID2', 'Label2', 0.4418604651162791), ('ID_Type2_2', 'ID3', 'Label3', 0.3958333333333333), ('ID_Type2_2', 'ID1', 'Label1', 0.35714285714285715)]                   
[('ID_Type2_5', 'ID2', 'Label2', 0.4958333333333333), ('ID_Type2_5', 'ID3', 'Label3', 0.35714285714285715)]

И теперь вы можете получить свой режим с помощьюпростой список списка каждой группы до m значений:

for k, g in groups.items():
    # label_mode_of_first_m_values_for_this_group = statistics.mode([label for idt2, idt1, label, val in g[:m]])
...