Многопроцессорная обработка со словарем объектов-генераторов, TypeError: невозможно выбрать объект-генератор - PullRequest
0 голосов
/ 22 марта 2020

Как я могу использовать многопроцессорность для создания словаря с объектами генератора в качестве значений?

Вот моя проблема более подробно, используя базовые c примеры:

У меня есть большой словарь списков, в котором я применяю функции для вычисления значений словаря, используя ProcessPoolExecutor в concurrent.futures. (Обратите внимание, что я использую ProcessPoolExecutor, а не потоки - здесь нет разногласий по GIL.)

Вот пример словаря списков:

example_dict1 = {'key1':[367, 30, 847, 482, 887, 654, 347, 504, 413, 821],
    'key2':[754, 915, 622, 149, 279, 192, 312, 203, 742, 846], 
    'key3':[586, 521, 470, 476, 693, 426, 746, 733, 528, 565]}

Это небольшой пример На самом деле это огромный словарь с миллионами ключей и списками с тысячами элементов.

Первоначально я обрабатывал эти списки значений с помощью функции, которая добавляет пустой список, например,

import concurrent

def manipulate_values(dict_items):
    k, v = dict_items
    return_values = []   ## empty list
    for i in v :
        new_value = i ** 2 - 13      ## compute something; just an example
        return_values.append(new_value)  ## append to list
    return k, return_values

with concurrent.futures.ProcessPoolExecutor() as executor:
        new_dict = dict(executor.map(manipulate_values, example_dict1.items()))

Однако полученные списки словарей return_values слишком велики для памяти. Поскольку я не могу хранить эти массивные списки в памяти, я решил попробовать функции генератора, то есть создать словарь ключей и объектов генератора:

## generator function
def compute_values(v):
    for i in v:
        yield i ** 2 - 13   ## using example above; could be any function call 

def manipulate_values_with_generator(dict_items):
    keys, value_lists = dict_items
    return keys, compute_values(value_lists)

with concurrent.futures.ProcessPoolExecutor() as executor:
        new_dict = dict(executor.map(manipulate_values_with_generator, example_dict1.items()))

В реальном словаре «больших данных» это приведет к ошибка травления:

TypeError: cannot pickle 'generator' object

Есть другие вопросы на эту тему, но я не уверен, как решить мою проблему - пакеты, такие как dill и pathos, не работают с генераторами.

Не могу мариновать при использовании многопроцессорной обработки Pool.map ()

Невозможно выбрать выражение Pyparsing с помощью метода setParseAction (). Необходим для многопроцессорной обработки

Естественно, возможно, есть еще один способ решения моей фундаментальной проблемы: многопроцессорная обработка большого словаря списков в памяти или генераторах. Может быть, другая структура данных будет полезна здесь?

...