Я пытаюсь создать функцию агрегирования акций с циклом по датам. По сути, я хочу суммировать переменную на основе группировки и итерации по датам. Однако у меня есть несколько записей для данного дня, что немного усложняет проблему. В настоящее время я использую pandas .groupby, но он работает слишком медленно для моих> 3-метровых строк, поэтому мне интересно, как я мог бы вместо этого векторизовать его.
Представленный некоторым примером кода, я хотел бы векторизовать ниже. Представьте, что я складываю что-то, скажем, яблоки для группы покупателей, и я хотел бы отслеживать, сколько яблок я складирую для каждого покупателя в любой день. Каждый клиент может внести «депозит» из нескольких яблок за один день до даты в будущем, и может сделать несколько депозитов каждый день. Пример кода выглядит так:
import pandas as pd
df = {'StartDate': ['2020-01-01','2020-01-01','2020-01-01','2020-01-02','2020-01-02','2020-01-02','2020-01-03','2020-01-04','2020-01-04','2020-01-05'],
'EndDate':['2020-01-02','2020-01-02','2020-01-05','2020-01-05','2020-01-03','2020-01-04','2020-01-06','2020-01-06','2020-01-06','2020-01-06'],
'Apples':[5,6,2,4,4,10,8,9,3,7],
'Customer':['A','B','A','C','A','A','B','B','C','A']}
df = pd.DataFrame(data=df)
cycledates = ['2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05','2020-01-06']
def stockfunction(indata, ingroupingvars, cycledates):
stock_agg = pd.DataFrame()
for i in cycledates:
stock_input = indata.loc[
(indata['StartDate'] <= i) & (indata['EndDate'] > i)]
stock_input['EvaluationDate'] = i
stock_marg = stock_input.groupby(ingroupingvars)['Apples'].sum().unstack(level=0)
stock_agg = stock_agg.append(stock_marg)
return stock_agg
ingroupingvars = ['Customer','EvaluationDate']
stock = stockfunction(df,ingroupingvars,cycledates)
Пример вывода
Кадр данных выглядит так:
StartDate EndDate Apples Customer
0 2020-01-01 2020-01-02 5 A
1 2020-01-01 2020-01-02 6 B
2 2020-01-01 2020-01-05 2 A
3 2020-01-02 2020-01-05 4 C
4 2020-01-02 2020-01-03 4 A
5 2020-01-02 2020-01-04 10 A
6 2020-01-03 2020-01-06 8 B
7 2020-01-04 2020-01-06 9 B
8 2020-01-04 2020-01-06 3 C
9 2020-01-05 2020-01-06 7 A
И конечный результат выглядит так:
Customer A B C
EvaluationDate
2020-01-01 7 6.0 NaN
2020-01-02 16 NaN 4.0
2020-01-03 12 8.0 4.0
2020-01-04 2 17.0 7.0
2020-01-05 7 17.0 3.0
... просто для того, чтобы мои исходные данные работали вечно.