Группировка по значениям словаря и удаление дубликатов из других групп

#python #pandas #dictionary

#python #pandas #словарь

Вопрос:

У меня есть словарь:

 {'a': ['b','c'],
'b':['e','f'],
'c':['g'],
'h':['m','n']}
  

Я хочу, чтобы мой словарь группировал его по сходству

вот как я хочу, чтобы словарь выглядел после обработки:

 {'a':['b','c','e','f','g'],
'h':['m','n']
}

  

есть ли какой-нибудь способ сделать это эффективно? Я хочу преобразовать этот словарь в фрейм данных pandas.

Редактировать:

На самом деле это сопоставление . Приведенный выше словарь означает. :

a = b, c b = e, f

следовательно, a = b, c, e, f аналогично, h = m, n (другое отображение значений)

Примечание: это основано исключительно на модели, которую я разрабатываю.

Комментарии:

1. Я думаю, вам нужно уточнить, что означает «сходство». Какая связь между h, m и n?

2. Используйте пользовательскую функцию для просмотра значений и объединения.

Ответ №1:

Не знаю точно, является ли это наиболее эффективным способом сделать это (вероятно, это не так), но вы можете попробовать следующее:

 def merge_entries(input_dict):
    to_delete = set()
    for k,v in input_dict.items():
        if k not in to_delete:
            for x in v:
                if x in input_dict.keys():
                    test[k] =test[x]
                    to_delete.add(x)

    for i in to_delete:
        del input_dict[i]

    return input_dict

test = {
'a': ['b','c'],
'b':['e','f'],
'c':['g'],
'h':['m','n']
}
print (merge_entries(test))
  

Я интерпретировал ваше слияние по сходству, если какое-либо значение key x совпадает с ключом y в словаре, затем объедините значения y в x .

Редактировать:

OP отредактировал демонстрационный набор данных следующим образом:

 test ={'a': ['b','c'],
'b':['e','f','c'],
'c':['g'],
'h':['m','n'],
'k':['c']}
  

В этом случае я собираюсь предположить, что ожидаемый ответ — это эти две группы:

 [{'g', 'e', 'k', 'f', 'b', 'c', 'a'}, {'h', 'n', 'm'}] 
  

Я также собираюсь предположить, что формат словаря вроде как не имеет значения, поскольку в новом примере OP словарная запись 'k':['c']} должна быть объединена значением c с первой группой. Итак, я предоставлю ответ в списке с n заданными записями.

 def merge_entries2(input_dict):
    results = []
    count = 0
    for k,v in input_dict.items():
        if count == 0: #initial state add a group
            nset=set(v)
            nset.add(k)
            results.append(nset)
            count =1
        else:
            for i,group in enumerate(results):
                nset = set(v)
                nset.add(k)
                if k in group:
                    results[i] = results[i].union(nset)
                    break
                                        
                else:
                    if len(nset.intersection(group)) > 0:
                        results[i]=results[i].union(nset)
                        break
                        
                    else:
                        results.append(nset)
                        break
                                      
    return results
test ={'a': ['b','c'],
'b':['e','f','c'],
'c':['g'],
'h':['m','n'],
'k':['c']}

print (merge_entries2(test))


  

Краткий обзор скрипта:
Если группа не определена, определите первую группу с объединенным значением key value из первой записи словаря. Затем для каждой другой словарной записи создайте новый набор с объединенным ключом и значением и проверьте, пересекается ли этот набор с любым существующим набором, если он объединяет их, если нет, создайте новую группу.

Ответ №2:

Переформатирование dict имеет побочные эффекты, но я считаю, что это понятно.

 d = {'a': ['b', 'c'], 'b': ['e', 'f'], 'c': ['g'], 'h': ['m', 'n']}
for k in list(d.keys()):
    # may have deleted the key,  check..
    if k in d.keys():
        for i in list(d[k]):
            # defined as another key, append and delete..
            if i in d.keys():
                d[k]  = d[i]
                del d[i]
# finally construct dataframe dict.  list sizes vary so use {"col":{id:val}} format               
df = pd.DataFrame({k:{i:v for i,v in enumerate(d[k])} for k in d.keys()})
print(d)
print(df.to_string(index=False))
  

вывод (dict, затем dataframe)

 {'a': ['b', 'c', 'e', 'f', 'g'], 'h': ['m', 'n']}
 a    h
 b    m
 c    n
 e  NaN
 f  NaN
 g  NaN