У меня есть список идентификаторов, которые я зацикливаю в цикле for для созданной мной функции.
Эта функция выполняет команду GET для API и преобразует JSON в pandas
DataFrame (df), после того, как вы передали ему словарь столбцов, которые вы хотели бы видеть.
Функция также выполняет некоторую перехват, в том случае, если у идентификатора нет строк, она создает пустой кадр данных с переданными именами столбцов, так что ширина столбца равна ожидаемому результату, но ничего не добавляет.Это предотвращает сбой запроса из-за несоответствующей ширины столбца во время конкатенации.
СПРОСИТЕЛИ: при прохождении этой функции по отношению к API она работает очень медленно.Я хотел бы иметь несколько циклов for и разделить идентичные наборы одинаково, скажем, посредством многопоточности или параллельной обработки.Подвох в том, что многие из найденных мной решений используют функцию map, которая просто имеет один параметр - список элементов.Мне также хотелось бы иметь возможность иметь константы.
Вот пример, с которым я пытался работать, используя functools
и concurrent.futures
.
Я был вдохновлен этой статьей: https://medium.com/@ageitgey/quick-tip-speed-up-your-python-data-processing-scripts-with-process-pools-cf275350163a
Проблема с этим подходом состоит в том, что он будет работать, но, по-видимому, неопределенно долго, не предоставляя мне данные.Мой оригинальный сценарий занимает некоторое время, но на самом деле дает мне мой фрейм данных.Возможно, мне нужен другой подход, или мой код требует изменений?Не уверен, что их подход лучше.
import concurrent.futures
import functools
# Create a pool of processes. By default, one is created for each CPU in your machine.
with concurrent.futures.ProcessPoolExecutor() as executor:
# Get a list of warehouse_id s to process for each item
target_list = list_of_warehouse_ids
#instantiate a empty dataframe filled with the column names
test_filler = pd.DataFrame(columns=list_of_warehouse_ids)
# Process the list of item_ids, but split the work across
#the process pool to use all CPUs!
for item, df in zip(target_list,executor.map(functools.partial(concat_tasks #function
,filling_df=test_filler #parameter
,iterator_input_func=json_fields #parameter
,col_list = list_of_standard_columns #parameter
), list_of_warehouse_ids #list of IDs
)
):
print(item, df)
Вот мой оригинальный пример, который я выписал, но для запуска может потребоваться некоторое время.
#these are not real
#list of ids to loop through
list_of_warehouse_ids = [
'C91G9'
,'3CJ77'
,'YP8NW'
,'6T5VY'
,'G862E'
,'CS7OS'
,'QY0AP'
,'QX30K'
,'O1FSO'
,'H3998'
,'C1W1M'
,'VV69A'
,'5MWRG'
,'45K37'
,'GN2B2'
]
#standard columns I want to see
list_of_standard_columns = [
'item_id'
,'item_name'
,'item_tags'
,'item_ship_date'
,'warehouse_id'
]
# dictionary that passes in the arguements for each JSON object
json_fields = {"fields":"item_id, item_name, item_tags, item_ship_date, warehouse_id"}
#make a new empty dataframe to start appending items by warehouse
to_fill_df = pd.DataFrame(columns=list_of_standard_columns)
#iterate through all the available projects_ids to get their associated tasks.
for row in list_of_warehouse_ids:
#execute query and get the items for a warehouse
row_items_df = ac.items_dataframe( warehouse_id = row
, iterator_input = json_fields
, cols = list_of_standard_columns )
#concate each dataframe
to_fill_df = pd.concat([to_fill_df, row_items_df])
#filled up dataframe with all items
items_by_warehouse_df = to_fill_df
Другая версия Iпопытался, кажется, не завершает выполнение, в то время как оригинальный цикл for занимает много времени (возможно, двойные цифры в минутах).