Подсчет вхождений в списке кортежей - PullRequest
0 голосов
/ 22 февраля 2019

Я думаю, что лучше всего начать с ввода и вывода:

list_of_items = [
    {"A": "abc", "B": "dre", "C": "ccp"},
    {"A": "qwe", "B": "dre", "C": "ccp"},
    {"A": "abc", "B": "dre", "C": "ccp"},
]

result = {'A-abc-->B': {'dre': 2},
          'A-abc-->C': {'ccp': 2},
          'A-qwe-->B': {'dre': 1},
          'A-qwe-->C': {'ccp': 1},
          'B-dre-->A': {'abc': 2, 'qwe': 1},
          'B-dre-->C': {'ccp': 3},
          'C-ccp-->A': {'abc': 2, 'qwe': 1},
          'C-ccp-->B': {'dre': 3}}

Мой первоначальный ввод - это элементы, которые поступают в виде потока.Эти предметы в основном словари с ключом и значением.Моя цель состоит в том, чтобы получить для каждого конкретного ключа и определить максимальное значение для всех остальных ключей, которые поставлялись вместе с ним.

Поэтому, если из 100 элементов, для ключа "A" со значением "1" я получил90 пунктов для ключа «B», значение «2» и из 10 элементов для ключа «B», значение «1111». Я хочу увидеть список, который покажет мне эти цифры.B2 = 90, B1111 = 10.

Мой код работает.Но мой реальный сценарий содержит более 100000 различных значений для примерно 20 ключей.Кроме того, моей конечной целью было бы выполнить это как работу на Flink.

Так что я ищу помощь с API Counter / python stream.

all_tuple_list_items = []
for dict_item in list_of_items:
    list_of_tuples = [(k, v) for (k, v) in dict_item.items()]
    all_tuple_list_items.append(list_of_tuples)

result_dict = {}
for list_of_tuples in all_tuple_list_items:
    for id_tuple in list_of_tuples:
        all_other_tuples = list_of_tuples.copy()
        all_other_tuples.remove(id_tuple)
        dict_of_specific_corresponding = {}

        for corresponding_other_tu in all_other_tuples:
            ids_connection_id = id_tuple[0] + "-" + str(id_tuple[1]) + "-->" + corresponding_other_tu[0]
            corresponding_id = str(corresponding_other_tu[1])

            if result_dict.get(ids_connection_id) is None:
                result_dict[ids_connection_id] = {corresponding_id: 1}
            else:
                if result_dict[ids_connection_id].get(corresponding_id) is None:
                    result_dict[ids_connection_id][corresponding_id] = 1
                else:
                    result_dict[ids_connection_id][corresponding_id] = result_dict[ids_connection_id][
                                                                           corresponding_id] + 1

pprint(result_dict)

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Вы можете использовать функцию permutations() для генерации всех перестановок предметов в диктах и ​​Counter для их подсчета.Наконец, вы можете использовать defaultdict() для группировки элементов из Counter:

from collections import Counter, defaultdict
from itertools import permutations
from pprint import pprint

list_of_items = [
    [{"A": "abc", "B": "dre", "C": "ccp"}],
    [{"A": "qwe", "B": "dre", "C": "ccp"}],
    [{"A": "abc", "B": "dre", "C": "ccp"}],
]

c = Counter(p for i in list_of_items       
              for p in permutations(i[0].items(), 2))
d = defaultdict(dict)
for ((i, j), (k, l)), num in c.items():
    d[f'{i}-{j}-->{k}'][l] = num

pprint(d)

Вывод:

defaultdict(<class 'dict'>,
            {'A-abc-->B': {'dre': 2},
             'A-abc-->C': {'ccp': 2},
             'A-qwe-->B': {'dre': 1},
             'A-qwe-->C': {'ccp': 1},
             'B-dre-->A': {'abc': 2, 'qwe': 1},
             'B-dre-->C': {'ccp': 3},
             'C-ccp-->A': {'abc': 2, 'qwe': 1},
             'C-ccp-->B': {'dre': 3}})
0 голосов
/ 22 февраля 2019

Получил это на работу.Но все еще хочет получить более эффективный способ.Использование счетчиков и потоков.это возможно?

код

all_tuple_list_items = []
for dict_item in list_of_items:
    list_of_tuples = [(k, v) for (k, v) in dict_item[0].items()]
    all_tuple_list_items.append(list_of_tuples)

result_dict = {}
for list_of_tuples in all_tuple_list_items:
    for id_tuple in list_of_tuples:
        all_other_tuples = list_of_tuples.copy()
        all_other_tuples.remove(id_tuple)
        dict_of_specific_corresponding = {}

        for corresponding_other_tu in all_other_tuples:
            ids_connection_id = id_tuple[0] + "-" + str(id_tuple[1]) + "-->" + corresponding_other_tu[0]
            corresponding_id = str(corresponding_other_tu[1])

            if result_dict.get(ids_connection_id) is None:
                result_dict[ids_connection_id] = {corresponding_id: 1}
            else:
                if result_dict[ids_connection_id].get(corresponding_id) is None:
                    result_dict[ids_connection_id][corresponding_id] = 1
                else:
                    result_dict[ids_connection_id][corresponding_id] = result_dict[ids_connection_id][
                                                                           corresponding_id] + 1

pprint(result_dict)
...