Как добавить и удалить однокадровые строки данных в кадре данных MultiIndex и из него? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть df, Stock_to_buy, который говорит, какую акцию покупать на данную дату. Индексный столбец: Date.

             Symbol   Shares
Date         
2018-01-01   AAOI     20
2018-01-03   FB       34
2018-01-05   AMZN     5
2018-01-07   SQ       25
2018-01-08   TPL      31

Я создал другой df, Portfolio. Я предполагаю, что решение требует, чтобы он был MultiIndex, поэтому столбцы индекса: Date и Symbol.

                       Shares
Date         Symbol
2018-01-01   NaN       NaN
2018-01-02   NaN       NaN
2018-01-03   NaN       NaN
2018-01-04   NaN       NaN
2018-01-05   NaN       NaN
2018-01-06   NaN       NaN
2018-01-07   NaN       NaN
2018-01-08   NaN       NaN

Я хочу обновить Portfolio на основе Stock_to_buy: если символ находится в Stock_to_buy на указанную дату, его следует добавить в виде строки к Portfolio на эту дату, и его следует сохранить там. в последующие даты, пока Sell_Next_Day не станет True, и в этом случае строка Symbol должна быть удалена из последующих дат. Ниже приведен пример, как я хочу, чтобы Portfolio работал.

                      Shares   Sell_Next_Day
Date         Symbol
2017-12-31   NaN      NaN      NaN 
---------------------------------------------        
2018-01-01   AAOI     20       False
---------------------------------------------
2018-01-02   AAOI     20       False
---------------------------------------------
2018-01-03   AAOI     20       False
             FB       34       False
---------------------------------------------
2018-01-04   AAOI     20       False
             FB       34       False
---------------------------------------------
2018-01-05   AAOI     20       False
             FB       34       False
             AMZN     5        False
---------------------------------------------
2018-01-06   AAOI     20       True           # AAOI will be sold next day
             FB       34       False
             AMZN     5        False
---------------------------------------------
2018-01-07   FB       34       False
             AMZN     5        True           # AMZN will be sold next day
             SQ       25       False
---------------------------------------------
2018-01-08   FB       34       False
             SQ       25       False
             TPL      31       False

Как я могу это сделать? Любая помощь приветствуется.

1 Ответ

0 голосов
/ 31 августа 2018

Я не уверен, что это именно то, что вы хотите, но я думаю, что это может быть полезно. Данные:

Stock_to_buy = pd.DataFrame(data=[
                                  ['2018-01-01','AAOI','20'],
                                  ['2018-01-03', 'FB', 34],
                                  ['2018-01-05', 'AMZN' , 5],
                                  ['2018-01-07', 'SQ', 25],
                                  ['2018-01-08', 'TPL' ,31]
                            ], columns=['Date', 'Symbol','Shares']
                           )
Stock_to_buy.Date = pd.to_datetime(Stock_to_buy.Date)

Шаг 1. Заполните все возможные значения.

END_DATE = Stock_to_buy.sort_values('Date').Date.values[-1]
def fill(df):
    index = pd.date_range(start=df.Date.values[0], end=END_DATE)
    return pd.DataFrame(data=[[1]*len(index)], index=index)

Portfolio = Stock_to_buy.groupby(['Symbol', 'Shares']
                    ).apply(fill).reset_index(
                    ).drop([i for i in range(0,8)], 1).rename(
                    columns={'level_2': 'Date'}).set_index('Date')

Выход:

           Symbol Shares
Date                    
2018-01-01   AAOI     20
2018-01-02   AAOI     20
2018-01-03   AAOI     20
2018-01-04   AAOI     20
2018-01-05   AAOI     20
2018-01-06   AAOI     20
2018-01-07   AAOI     20
2018-01-08   AAOI     20
2018-01-05   AMZN      5
2018-01-06   AMZN      5
2018-01-07   AMZN      5
2018-01-08   AMZN      5
2018-01-03     FB     34
2018-01-04     FB     34
2018-01-05     FB     34
2018-01-06     FB     34
2018-01-07     FB     34
2018-01-08     FB     34
2018-01-07     SQ     25
2018-01-08     SQ     25
2018-01-08    TPL     31

Шаг 2. Если у нас есть столбец Sell_Next_Day, например:

Sell_Next_Day = pd.Series([False, False, False, False, False, True, False, 
                           False, False, False, True, False, False, False, False,
                           False,False,False, False, False, False],
                           name='Sell_Next_Day')

Затем мы можем присоединиться к ним и отбросить все следующие строки после того, как Symbol будет иметь значение True в Sell_Next_Day.

def drop_dates(df):
    if df.Sell_Next_Day.any():
        res = df[df.Date <= df[df.Sell_Next_Day == True].Date.values[0]]
    else:
        res = df
    return res

Portfolio = Portfolio.reset_index().join(Sell_Next_Day
                            ).groupby('Symbol'
                            ).apply(drop_dates).set_index('Date')

Выход:

           Symbol Shares  Sell_Next_Day
Date                                   
2018-01-01   AAOI     20          False
2018-01-02   AAOI     20          False
2018-01-03   AAOI     20          False
2018-01-04   AAOI     20          False
2018-01-05   AAOI     20          False
2018-01-06   AAOI     20           True
2018-01-05   AMZN      5          False
2018-01-06   AMZN      5          False
2018-01-07   AMZN      5           True
2018-01-03     FB     34          False
2018-01-04     FB     34          False
2018-01-05     FB     34          False
2018-01-06     FB     34          False
2018-01-07     FB     34          False
2018-01-08     FB     34          False
2018-01-07     SQ     25          False
2018-01-08     SQ     25          False
2018-01-08    TPL     31          False

Это то, что вы хотите?

...