Первый dataframe: inj_2014 (35040, 991), в котором ссылки столбцов соответствуют тому, что называется EAN.Нужна помощь в оптимизации цикла с 3-мя кадрами данных
Date 541448860005060119 541448860003851078 ...
0 2014-01-01 00:00:00 0.0 0.0
1 2014-01-01 00:15:00 0.1 0.0
...
Второй информационный кадр: db (1125,17). Здесь EAN перегруппированы в один столбец. Есть больше строк, чем 991, потому что они соответствуют спецификациям контракта: если контракты заканчиваются в феврале 2014 года и начинаются снова в марте 2014 года, в df есть 2 строки. Колонки сд и редактор соответствуют дате начала и дате окончания
EAN sd ed ...
0 541448860008422181 2014-07-02 2017-01-03
1 541449200002077458 2012-01-04 2014-05-07
...
Третьего dataframe: цены (1125,9). В основном каждый EAN имеет различные спецификации цена, что изменения в течение года (Q1-Q2-Q3-Q4) и время (пик offpeak)
Q1_peak Q1_off_peak ... Q4_off_peak EAN
0 82.0264 56.9196 61.9826 541448860008422181
1 85.2736 57,8456 58,7564 541449200002077458
...
Что я хочу сделать: умножить число (т.е. инъекции) в inj_2014 по цене и положил его в новом dataframe, принимая во внимание:
- тот факт, что инъекции не следует рассчитывать, если дата не в рамках договора (или возвращать 0)
- факт, что два разных контракта могут иметь один и тот же EAN, и поэтому 2 разных столбца должны быть выходными (для Пример EAN_1 для более позднего контракта)
- того факта, что цена, по которым инъекции следует умножать зависит как дату и EAN
Я уже написал несколько ПОЛЕЗНЫХ функций:
def in_contrat(date, sd, ed):
'''True if date within date limits'''
if sd < date < ed:
return True
else:
return False
def price_name(date, dates_2014): #dates_2014 = list of the quarter limit dates
'''returns price name corresponding to the given date'''
if date < date_2014[1]:
if peak(date):
return 'Q1_peak'
else:
return 'Q1_off_peak'
elif date < date_2014[2]:
if peak(date):
return 'Q2_peak'
...
def in_contrat(date, sd, ed):
'''True if date within date limits'''
if sd < date < ed:
return True
else:
return False
def get_index(df, test):
'''returns list with index occurences of the specific EAN number in the db'''
index = []
for i in range(len(df)):
if df['EAN'][i] == test:
index.append(i)
return index
Так с этим материалом, я попытался написать свой мастер-функции:
def daily_calculation(inj_2014, db, prices):
list_EAN = []
for i in range(len(db)):
EAN = db['EAN'][i]
if EAN not in list_EAN:
list_EAN.append(EAN)
index = get_index(prices, EAN)[0]
else :
index = get_index(prices, EAN)[1]
for j in range(len(inj_2014)):
date = inj_2014['Date'][j]
name = price_name(date, dates_2014)
EBIQ = prices[name][index]
valeur_injection = inj_2014[EAN][j]/4000
if in_contrat(date, db['sd'][i], db['ed'][i]) and inj_2014[EAN][j] != 0:
results.set_value(j, EAN, (valeur_injection)*EBIQ)
else:
results.set_value(j, EAN, 0)
return results
Так что вещь, это, кажется, работает. Однако, учитывая время, когда мне потребовалось вычислить только первый столбец, мне нужно от 80 до 100 часов, чтобы получить мои результаты, и они могут даже ошибиться. Я могу справиться с несколькими днями, когда вы обнаружите ошибку-запустить-найти misake -... но не через несколько месяцев.
Я уверен, что есть способ оптимизировать этот цикл, получить огромное количество времени (мне уже удалось получить от 200 до 100 часов). Тем не менее, я довольно новичок в python/pandas/etc, и у меня нет опыта для его оптимизации; это отчаянный призыв.
Спасибо, я уже попробую! –