Pandas P & L на следующий рабочий день - PullRequest
1 голос
/ 10 октября 2019

Я с трудом пытаюсь сделать это эффективно. У меня есть несколько акций и ежедневная информация о прибылях и убытках в данных. На самом деле у меня миллионы строк данных, поэтому эффективность очень важна! Датафрейм выглядит следующим образом:

-------------------------------
| Date       | Security | P&L |
-------------------------------
| 2016-01-01 | AAPL     | 100 |
-------------------------------
| 2016-01-02 | AAPL     | 200 |
-------------------------------
| 2016-01-03 | AAPL     | 300 |
-------------------------------
| 2016-01-04 | AAPL     | -200 |
-------------------------------

Все, что я хочу сделать, это перенести отчет о прибылях и убытках на следующий рабочий день (исключая все выходные и выходные в США). Таким образом, результирующий кадр данных выглядит следующим образом:

-------------------------------
| Date       | Security | P&L |
-------------------------------
| 2016-01-04 | AAPL     | 400 |
-------------------------------

Я ищу эффективный способ добиться этого. У меня есть тысячи ценных бумаг и более 5 лет данных для обработки, так что грубая сила не может работать, к сожалению!

Заранее спасибо и высоко ценю любые указания на это!

Ответы [ 2 ]

4 голосов
/ 10 октября 2019

Мы можем создать DataFrame бизнес-дат, тогда merge_asof. Тогда мы можем сгруппировать это, чтобы получить суммы.

import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar

#df['Date'] = pd.to_datetime(df.Date)
date_min = '2015-01-01'
date_max = '2016-12-31'

cal = USFederalHolidayCalendar()
holidays = cal.holidays(date_min, date_max).tolist()
df2 = pd.DataFrame({'bdate': pd.bdate_range(date_min, date_max, 
                                            holidays=holidays, freq='C')})

res = pd.merge_asof(df, df2, left_on='Date', right_on='bdate', direction='forward')
#        Date Security  P&L      bdate
#0 2016-01-01     AAPL  100 2016-01-04
#1 2016-01-02     AAPL  200 2016-01-04
#2 2016-01-03     AAPL  300 2016-01-04
#3 2016-01-04     AAPL -200 2016-01-04

res.groupby(['Security', 'bdate'])['P&L'].sum()
#Security  bdate     
#AAPL      2016-01-04    400
1 голос
/ 11 октября 2019

IIUC вы можете сделать что-то вроде:

import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar
import numpy as np

date_min = '2015-01-01'
date_max = '2016-12-31'

cal = USFederalHolidayCalendar()
holidays = cal.holidays(date_min, date_max).tolist()

df = pd.DataFrame({"Date":pd.date_range(date_min, date_max)})
df["Security"] ="APPL"
df["P&L"] = np.random.randint(-1000, 1000, len(df))

df[~df["Date"].isin(holidays)].groupby("Security")\
                              .agg({"Date":"max",
                                    "P&L":"sum"})\
                              .reset_index()



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