Как сгруппировать повторяющиеся статьи словаря ⇐ Python
-
Anonymous
Как сгруппировать повторяющиеся статьи словаря
У меня есть словарь таких записей:
{ 'А': { 'HUE_SAT': 1, 'GROUP_INPUT': 1, 'GROUP_OUTPUT': 1 }, 'Д': { 'HUE_SAT': 1, 'GROUP_INPUT': 1, 'GROUP_OUTPUT': 1 }, 'Т': { 'HUE_SAT': 1, 'GROUP_INPUT': 1, 'GROUP_OUTPUT': 1 }, 'О': { 'GROUP_INPUT': 3, «КАРТИРОВАНИЕ»: 2, 'TEX_NOISE': 2, «УВМАП»: 2, 'ВАЛТОРГБ': 3, 'GROUP_OUTPUT': 1, 'AMBIENT_OCCLUSION': 1, «МИКС»: 4, «ПЕРЕСЫЛКА»: 1, 'NEW_GEOMETRY': 1, 'VECT_MATH': 1 }, Каждый элемент сравнивается друг с другом и получает оценку сходства. Затем создается словарь с кортежем из двух сравниваемых записей в качестве ключей и их показателем сходства в качестве значений. Проблема в том, что я получаю много повторяющихся записей, подобных этой:
{ («А», «Д»): 1,0, («А», «С»): 1,0, («Д», «А»): 1,0, («Д», «С»): 1,0, («С», «А»): 1,0, («С», «D»): 1,0, Я хочу сгруппировать ключи, если все они имеют одинаковую оценку сходства по сравнению друг с другом, например:
{ («А», «Г», «С»): 1,0, («О», «Л», «С», «Н», «П»): 0,412 Код:
# Функция косинусного подобия отсюда: # https://stackoverflow.com/a/35981085/22855942 защита Square_root (х): return round(sqrt(sum([a * a for a in x])), 3) Защиту cosine_similarity(a, b): ввод1 = {} вход2 = {} вектор1 = [] вектор2 = [] если len(a) > len(b): вход1 = а вход2 = б еще: вход1 = б вход2 = а вектор1 = список(input1.values()) для k в input1.keys(): если k во входе2: вектор2.append(float(input2[k])) еще: вектор2.append(с плавающей запятой(0)) числитель = сумма (a * b для a, b в zip (вектор2, вектор1)) знаменатель = квадратный_корень(вектор1) * квадратный_корень(вектор2) return round(числитель / float(знаменатель), 3) ключи = кортеж(my_dict.keys()) результаты = {} для k в ключах: для l в клавишах: если l != k: результаты[(k, l)] = results.get((l, k), cosine_similarity(my_dict[k], my_dict[l])) результаты = {ключ: значение для ключа, значение в сортировке (results.items(), ключ = лямбда-элемент: элемент [1], обратное = True)} Я пытался создать своего рода «буфер» сравниваемых пар, сравнивая текущий элемент с последним элементом списка буферов, добавляя их в зависимости от оценки сходства – но это быстро превратилось в путаницу вложенных циклов for, условных операторов и подсписки, когда я чувствую, что должно быть гораздо более элегантное решение?
У меня есть словарь таких записей:
{ 'А': { 'HUE_SAT': 1, 'GROUP_INPUT': 1, 'GROUP_OUTPUT': 1 }, 'Д': { 'HUE_SAT': 1, 'GROUP_INPUT': 1, 'GROUP_OUTPUT': 1 }, 'Т': { 'HUE_SAT': 1, 'GROUP_INPUT': 1, 'GROUP_OUTPUT': 1 }, 'О': { 'GROUP_INPUT': 3, «КАРТИРОВАНИЕ»: 2, 'TEX_NOISE': 2, «УВМАП»: 2, 'ВАЛТОРГБ': 3, 'GROUP_OUTPUT': 1, 'AMBIENT_OCCLUSION': 1, «МИКС»: 4, «ПЕРЕСЫЛКА»: 1, 'NEW_GEOMETRY': 1, 'VECT_MATH': 1 }, Каждый элемент сравнивается друг с другом и получает оценку сходства. Затем создается словарь с кортежем из двух сравниваемых записей в качестве ключей и их показателем сходства в качестве значений. Проблема в том, что я получаю много повторяющихся записей, подобных этой:
{ («А», «Д»): 1,0, («А», «С»): 1,0, («Д», «А»): 1,0, («Д», «С»): 1,0, («С», «А»): 1,0, («С», «D»): 1,0, Я хочу сгруппировать ключи, если все они имеют одинаковую оценку сходства по сравнению друг с другом, например:
{ («А», «Г», «С»): 1,0, («О», «Л», «С», «Н», «П»): 0,412 Код:
# Функция косинусного подобия отсюда: # https://stackoverflow.com/a/35981085/22855942 защита Square_root (х): return round(sqrt(sum([a * a for a in x])), 3) Защиту cosine_similarity(a, b): ввод1 = {} вход2 = {} вектор1 = [] вектор2 = [] если len(a) > len(b): вход1 = а вход2 = б еще: вход1 = б вход2 = а вектор1 = список(input1.values()) для k в input1.keys(): если k во входе2: вектор2.append(float(input2[k])) еще: вектор2.append(с плавающей запятой(0)) числитель = сумма (a * b для a, b в zip (вектор2, вектор1)) знаменатель = квадратный_корень(вектор1) * квадратный_корень(вектор2) return round(числитель / float(знаменатель), 3) ключи = кортеж(my_dict.keys()) результаты = {} для k в ключах: для l в клавишах: если l != k: результаты[(k, l)] = results.get((l, k), cosine_similarity(my_dict[k], my_dict[l])) результаты = {ключ: значение для ключа, значение в сортировке (results.items(), ключ = лямбда-элемент: элемент [1], обратное = True)} Я пытался создать своего рода «буфер» сравниваемых пар, сравнивая текущий элемент с последним элементом списка буферов, добавляя их в зависимости от оценки сходства – но это быстро превратилось в путаницу вложенных циклов for, условных операторов и подсписки, когда я чувствую, что должно быть гораздо более элегантное решение?
Мобильная версия