Я не уверен, что заголовок хорошо описывает мой вопрос, но если что-то не так, я отредактирую позже. Я проверил много вопросов, связанных с этим, но с тех пор, как код настолько вложен, я не очень опытен в программировании, и мне нужно использовать combinations
Я не могу справиться.
У меня есть вложенныйdict, который похож на это:
example_dictionary = {'I want to eat peach and egg.':{'apple':3, 'orange':2, 'banana':5},\
'Peach juice is so delicious.':{'apple':3, 'orange':5, 'banana':2}, \
'Goddamn monkey ate my banana.':{'rice':4, 'apple':6, 'monkey':2}, \
'They say apple is good for health.':{'grape':10, 'monkey':5, 'peach':5, 'egg':8}}
Я пытаюсь создать матрицу смежности, следуя некоторым правилам. Правила таковы:
1) Если слово в любом внутреннем изречении существует в каком-либо предложении (внешние ключи), то добавьте вес в качестве значения слова между связанными предложениями.
2) Если любое из двух предложений имеет один и тот же внутренний ключ dict (слово), но разные значения, умножьте значения слов и добавьте в качестве веса между связанными предложениями.
Дополнительное примечание: внутренние дикты могутимеют разную длину, одни и те же внутренние ключи (слова) могут иметь разные значения. Я хочу, чтобы они умножались только в этом случае, если они имеют одинаковые значения, которые я не хочу принимать во внимание.
Пример:
Sentence1(0): I want to eat peach and egg. {'apple':3, 'orange':2, 'banana':5}
Sentence2(1): Peach juice is so delicious. {'apple':3, 'orange':5, 'banana':2}
Sentence3(2): Goddamn monkey ate my banana.{'rice':4, 'apple':6, 'monkey':2}
Sentence4(3): They say apple is good for health. {'grape':10, 'monkey':5, 'peach':5, 'egg':8}
Между 0 и1: 5 * 2 + 5 * 2 = 20 (потому что их яблоки имеют одинаковое значение, просто умножили значения для апельсина и банана. И ни одно из слов не существует ни в одном предложении.)
Между 2 и 3: (2 * 5 = 10 (обезьяна - это тот же ключ с другим значением) +
6 (ключ предложения3 'яблоко 'существует в предложении 4) +
5 (ключ предложения 4' обезьяна 'существует в предложении 3) = 21
от 0 до 3: 3 + 5 + 8 = 16 (в предложении 4 имеется ключ 'яблоко' предложения 1, а в предложении 1 присутствуют клавиши 'яйцо' и 'персик' предложения 4.
Я надеюсь, чтопримеры проясняют.
То, что я пробовал (меня это сильно смущало из-за вложенной структуры и комбинаций):
from itertools import combinations, zip_longest
import networkx as nx
def compare_inner_dicts(d1,d2):
#this is for comparing the inner dict keys and multiplying them
#if they have the same key but different value
values = []
inner_values = 0
for common_key in d1.keys() & d2.keys():
if d1[common_key]!= d2[common_key]:
_value = d1[common_key]*d2[common_key]
values.append(_value)
inner_values = sum([p for p in values])
inner_dict_values = inner_values
del inner_values
return inner_dict_values
def build_adj_mat(a_dict):
gr = nx.Graph()
for sentence, words in a_dict.items():
sentences = list(a_dict.keys())
gr.add_nodes_from(sentences)
sentence_pairs = combinations(gr.nodes, 2)
dict_pairs = combinations(a_dict.values(), 2)
for pair, _pair in zip_longest(sentence_pairs, dict_pairs):
numbers = []
x_numbers = []
#y_numbers = []
sentence1 = pair[0]
sentence2 = pair[1]
dict1 = _pair[0]
dict2 = _pair[1]
inner_dict_numbers = compare_inner_dicts(dict1, dict2)
numbers.append(inner_dict_numbers)
for word, num in words.items():
if sentence2.find(word)>-1:
x = words[word]
x_numbers.append(x)
numbers.extend(x_numbers)
# if sentence1.find(word)>-1: #reverse case
# y = words[word]
# y_numbers.append(y)
# numbers.extend(y_numbers)
total = sum([p for p in numbers if len(numbers)>0])
if total>0:
gr.add_edge(sentence1, sentence2, weight=total)
del total
else: del total
else:
continue
numbers.clear()
x_numbers.clear()
#y_numbers.clear()
return gr
G = build_adj_mat(example_dictionary)
print(nx.adjacency_matrix(G))
Ожидаемый результат:
(0, 1) 5*2+5*2=20
(0, 2) 3*6=18+5=23
(0, 3) 3+5+8=16
(1, 0) 20
(1, 2) 3*6=18+2=20
(1, 3) 3+5=8
(2, 0) 23
(2, 1) 20
(2, 3) 2*5=10+5+6=21
(3, 0) 16
(3, 1) 8
(3, 2) 21
Выход:
(0, 2) 23
(0, 3) 6
(1, 2) 23
(1, 3) 6
(2, 0) 23
(2, 1) 23
(2, 3) 16
(3, 0) 6
(3, 1) 6
(3, 2) 16
Сравнивая ожидаемый вывод и сравниваемый вывод, я могу понять одну из проблем, которая заключается в том, что мой код просто проверяет, существует ли слово в sentence1
в sentence2
, но не делает обратное,Я пытался решить эту проблему, используя закомментированную часть, но это дало больше бессмысленных результатов. Также я не уверен, есть ли какие-либо другие проблемы. Я не знаю, как получить правильный результат, эти две комбинации и вложенная структура делают меня полностью потерянным. Извините за длинный вопрос, чтобы было понятно, я все описал. Любая помощь будет принята с благодарностью, заранее спасибо.