Python - запуск функции одновременно (несколько экземпляров) - PullRequest
0 голосов
/ 13 ноября 2018

Я создал небольшую функцию, которая будет собирать некоторые данные, используя сторонний API. Вызовите if def MyFunc(Symbol, Field), который вернет некоторую информацию на основе заданного символа.

Идея состояла в том, чтобы заполнить dand Pandas возвращаемым значением, используя что-то вроде:

df['MyNewField'] = df.apply(lamba x: MyFunc(x, 'FieldName'))

Все это работает НО , каждый запрос занимает около 100мс для выполнения. Это кажется быстрым, пока вы не поймете, что у вас может быть 30000 или более (3000 символов с 10 полями для каждого для начинающих).

Мне было интересно, будет ли способ выполнить это одновременно, поскольку каждый запрос независим? Я не ищу многопроцессорных и т. Д. Библиотек, а вместо этого могу одновременно выполнять несколько запросов к сторонним организациям, чтобы сократить время, необходимое для сбора всех данных. (Кроме того, я полагаю, что это изменит исходную структуру, используемую для хранения всех полученных данных - я не против сначала не использовать Apply и мой dataframe, а вместо этого сохранять данные в том виде, в каком они получены в структуре текстового или библиотечного типа -).

ПРИМЕЧАНИЕ. Хотелось бы изменить MyFunc для одновременного запроса нескольких символов / полей, но это не может быть сделано для всех случаев (то есть некоторые поля не позволяют этого, и единственный запрос - единственный способ). Вот почему я смотрю на параллельное выполнение, а не на изменение MyFunc.

Спасибо!

1 Ответ

0 голосов
/ 13 ноября 2018

Существует много библиотек для распараллеливания панд данных. Тем не менее, я предпочитаю, чтобы родной мультипроцессорный пул делал то же самое. Кроме того, я использую tqdm вместе с ним, чтобы узнать прогресс.

import numpy as np
from multiprocessing import cpu_count, Pool

cores = 4 #Number of CPU cores on your system
partitions = cores #Define as many partitions as you want

def partition(data, num_partitions):
    partition_len = int(len(data)/num_partitions)
    partitions = []

    num_rows = 0
    for i in range(num_partitions-1):
        partition = data.iloc[i*partition_len:i*partition_len+partition_len]
        num_rows = num_rows + partition_len
        partitions.append(partition)

    partitions.append(data.iloc[num_rows:len(data)])
    return partitions

def parallelize(data, func):
    data_split = partition(data, partitions)
    pool = Pool(cores)
    data = pd.concat(pool.map(func, data_split))
    pool.close()
    pool.join()
    return data

df['MyNewField'] = parallelize(df['FieldName'], MyFunc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...