Альтернатива Python For Loop для более быстрых результатов - PullRequest
0 голосов
/ 08 июля 2019

Вот моя ситуация. Я пытаюсь создать огромную базу данных, содержащую все исторические данные (с 01.01.2017 г. по 30.06.2009 г.) о запасах NYSE & NASDAQ и их индикаторах.

Все запасы 4000+ хранятся в одной таблице с именем «ALLSTOCKS». Эта таблица обновляется ежедневно с помощью моей загрузки CSV.

CSV-загрузка содержит открытия, максимумы, минимумы и цены закрытия каждой отдельной акции, которые будут храниться из соответствующих столбцов. Исходя из этих чисел, мой код Python будет автоматически выполнять вычисления. Хорошим примером таких вычислений являются средние значения закрытия за 9, 20, 50 и 100 дней.

Для этого я извлекаю последние 9, 20, 50 и дни ЗАКРЫТЬ каждой акции, выполняю простую функцию mysql AVG () и сохраняю ее в назначенном столбце (MA9) из базы данных «ALLSTOCK».

Я уже упоминал, что акций более 4000, не так ли? Поэтому я решил заключить среднюю формулу в цикл LOOP.

Вот немного моего кода:

for ticker in tickers:

mycursor.execute("SELECT format(AVG(Close),4) from (select Close from _PSEI where stock = '" + ticker + "' ORDER BY ID DESC LIMIT 0,9) _PSEI")
manine = mycursor.fetchone()[0]

mycursor.execute("SELECT format(AVG(Close),4) from (select Close from _PSEI where stock = '" + ticker + "' ORDER BY ID DESC LIMIT 0,20) _PSEI")
matwenty = mycursor.fetchone()[0]

В любом случае, проблема в том, что это цикл for с переменным массивом, который содержит более 4000 элементов. Я получаю медленные результаты. Это означает, что мой код выполняется примерно от 0,3 до 0,5 секунды на каждую акцию, и для завершения всего цикла потребуется не более 2000 секунд.

Вот (часть) массива переменных:

ticker = ["CHK","BAC","GE","VALE","T","F","PFE","GGB","ECA","SWN","BBD","GME","RRC","FCX","AUY","AVP","APC","KGC","PBR","WFC","S","NBR","DB","C","SAN","KO","PG","RIG","HAL","MRK","X","NOK","APA","DNR","JPM","NLY","MRO","GFI","VZ","RF","XOM","NEM","NKE","HPQ","MS","CLF","DAL","SLB","M","ESV","V","KR","CTL","KEY","JCP","OXY","DIS","BP","CIG","EOG","IAG","MO","GM","RIO","EQT","GOL","HMY","ABB","DVN","MGM"]

Есть ли способ сделать это быстрее? Какой быстрый подход, который вы можете предложить? Как бы вы это сделали, если бы у вас была такая ситуация?

1 Ответ

1 голос
/ 08 июля 2019

Это занимает так много времени, потому что вы выполняете запрос (вызов БД) для каждого из 4000+ акций.

Я бы попытался выполнить один запрос, который проверяет все акции, например:

mycursor.execute("SELECT ... where stock in ('CHK', 'GE', 'BAC', ...) ...")

Компромисс будет хорошим, потому что этот один сложный запрос будет вызываться только один раз (против ~ 4000 запросов, которые выполняются так, как он выполняется в настоящее время).

Как правило, с точки зрения производительности лучше выполнять меньше вызовов в БД (и приносить больше данных при каждом вызове), чем наоборот, поскольку накладные расходы для каждого вызова велики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...