【问题标题】:Fill missing dates in a MultiIndex DataFrame with Pandas用 Pandas 填充 MultiIndex DataFrame 中缺失的日期
【发布时间】:2021-09-03 06:18:15
【问题描述】:

我有一个看起来像这样的 DataFrame

In [10]: vlr
Out[10]: 
               data tipoOP   qtd  ...       flxCx  flxCx_USD pmAtual_USD
ticker                            ...                                   
JBSS3.SA 2020-03-06      C   4.0  ...  -86.390000        NaN         NaN
WEGE3.SA 2020-08-27      C   3.0  ... -198.050000        NaN         NaN
ITUB4.SA 2020-09-09      C   8.0  ... -195.180000        NaN         NaN
WEGE3.SA 2020-09-09      V  -3.0  ...  193.150000        NaN         NaN
ITSA4.SA 2020-09-18      C  33.0  ... -297.430000        NaN         NaN
            ...    ...   ...  ...         ...        ...         ...
ARZZ3.SA 2021-06-01      C   2.0  ... -174.610000        NaN         NaN
CP       2021-06-02      C   1.0  ... -417.103785     -81.55       81.55
HSY      2021-06-02      C   1.0  ... -884.843100    -173.00      173.00
ARKQ     2021-06-02      V  -2.0  ...  836.650400     163.60         NaN
JPM      2021-06-02      C   1.0  ... -853.745724    -166.92      166.92

那我在做:

vlr_full = vlr.groupby('data')
vlr_full = vlr_full.apply(holding.ord_ativo).drop(columns=['data'])
vlr_full = vlr_full['qtdAtual']

获取vlr_full(qtdAtual栏为当天拥有的资产数量,累计):

In [12]: vlr_full
Out[12]: 
data        ticker  
2020-03-06  JBSS3.SA     4.0
2020-08-27  WEGE3.SA     3.0
2020-09-09  ITUB4.SA     8.0
            WEGE3.SA     0.0
2020-09-18  ITSA4.SA    33.0

2021-06-01  PRIO3.SA    50.0
2021-06-02  ARKQ         0.0
            CP           1.0
            HSY          1.0
            JPM          1.0
Name: qtdAtual, Length: 125, dtype: float64

(qtdAtual 表示“拥有的股份”,由vlr中“qtd”列的股票代码的累计和给出)

我有一个这样的DatetimeIndex:

idx = pd.date_range(first_day,end=yesterday,freq='D')

这是我买东西的第一天,一直到昨天

我的目标是用缺失的日期填充vlr_full“数据”级别索引,并且对于每个日期都有一个包含vlr 的所有代码的索引。如果代码在给定日期未交易,我将保留之前的值(如果尚未交易,则为 0)。有了这个,我计划使用yfinance 模块来获取历史报价数据并将其插入(乘以我在该日期拥有的数量)作为新列。之后我会绘制一些东西。

我试过这样的东西:

vlr_full.reindex(idx)

但是,显然它不起作用 (ValueError: cannot handle a non-unique multi-index!) 。我不确定如何继续,我尝试了一些相关的问题,但我无法将它们应用于我的问题。我确信有一些代码可以解决这个问题,但我正在学习。

至于我正在寻找的输出,它会是这样的:

In [12]: vlr_full
Out[12]: 
data        ticker  
2020-03-06  ABEV3.SA     0.0
            AMD          0.0
            ARKQ         0.0
            ARRZ3.SA     0.0
            CP           0.0
            HSY          0.0
            ITUB4.SA     0.0
            ITSA4.SA     0.0
            JBSS3.SA     4.0
...         ...          ...
2020-03-07  ABEV3.SA     0.0
            AMD          0.0
            ARKQ         0.0
            ARRZ3.SA     0.0
            CP           0.0
            HSY          0.0
            ITUB4.SA     0.0
            ITSA4.SA     0.0
            JBSS3.SA     4.0
...           ...        ...
...           ...        ...
2021-06-17  ABEV3.SA     45
            AMD          5
            ARKQ         0
            ARRZ3.SA     12
            CP           1
            HSY          1
            ITUB4.SA     0.0
            ITSA4.SA     139
            JBSS3.SA     0.0

因此,对于每个日期,从 2020 年 3 月 6 日(第一个日期)到昨天(截至今天的 2021 年 6 月 17 日),我希望有一个指数水平贯穿我交易过的所有代码指向并在该日期放置所拥有的股票(如果之前没有交易,则为零)。 我的问题是在第一级填写缺失的日期,然后在第二级填写股票代码。

请注意,在输出示例中,我在 2020 年 3 月 6 日只有 4 股 JBSS3.SA,仅此而已,直到 2020 年 8 月 27 日才会如此,同时仍将所有其他股票归为 0 股。

EDIT1:

试过这个:

vlr_full.reindex(pd.MultiIndex.from_product([idx,vlr_full.index.unique(level=1)], names=['data', 'ticker']), fill_value=0)

但它给了我:

ValueError: cannot handle a non-unique multi-index!

idx 是:

In [29]:idx
Out[29]: 
DatetimeIndex(['2020-03-06', '2020-03-07', '2020-03-08', '2020-03-09',
               '2020-03-10', '2020-03-11', '2020-03-12', '2020-03-13',
               '2020-03-14', '2020-03-15',
               ...
               '2021-06-08', '2021-06-09', '2021-06-10', '2021-06-11',
               '2021-06-12', '2021-06-13', '2021-06-14', '2021-06-15',
               '2021-06-16', '2021-06-17'],
              dtype='datetime64[ns]', length=469, freq='D')

而vlr_full.index.unique(level=1) 是:

In [30]:vlr_full.index.unique(level=1)
Out[30]: 
Index(['JBSS3.SA', 'WEGE3.SA', 'ITUB4.SA', 'ITSA4.SA', 'CPFE3.SA', 'TAEE11.SA',
       'VIVT4.SA', 'OIBR3.SA', 'TAEE4.SA', 'EGIE3.SA', 'SAPR11.SA', 'TIMS3.SA',
       'EQTL3.SA', 'VIVT3.SA', 'ABEV3.SA', 'HGLG11.SA', 'LEVE3.SA', 'RAIL3.SA',
       'XPLG11.SA', 'TAEE3.SA', 'ARKQ', 'ARZZ3.SA', 'GME', 'AMD', 'DIS',
       'EZTC3.SA', 'FLRY3.SA', 'RIO', 'FTM', 'JALL3.SA', 'PRIO3.SA',
       'BLAU3.SA', 'CP', 'HSY', 'JPM'],
      dtype='object', name='ticker')

【问题讨论】:

  • 我不明白你想做什么。也许你可以给出一些你期望的输出。您可能想使用vlr_full.reset_index()? (我问)
  • 我编辑了一些我想要的输出示例。我尽量保持小,因为它的所有日期都到昨天为止。我希望它变得更加清晰。
  • 谢谢,我明白了(也许...),现在尝试解决...

标签: python pandas pandas-groupby multi-index


【解决方案1】:

从vlr_full 开始,如下所示:

vlr_full
                   qtdActual
data       ticker           
2021-01-02 STACK         3.0
           OVER          2.0
2021-01-04 OVER          5.0
           FLOW          4.0
2021-01-06 STACK         6.0

执行以下操作。

# Change this to your own idx
idx = pd.date_range('2021-01-01', '2021-01-07', freq='D')
(
    vlr_full
    .unstack('ticker')
    .reindex(idx)
    .ffill()
    .fillna(0.0)
    .stack('ticker')
)

哪个输出:

                   qtdActual
           ticker           
2021-01-01 FLOW          0.0
           OVER          0.0
           STACK         0.0
2021-01-02 FLOW          0.0
           OVER          2.0
           STACK         3.0
2021-01-03 FLOW          0.0
           OVER          2.0
           STACK         3.0
2021-01-04 FLOW          4.0
           OVER          5.0
           STACK         3.0
2021-01-05 FLOW          4.0
           OVER          5.0
           STACK         3.0
2021-01-06 FLOW          4.0
           OVER          5.0
           STACK         6.0
2021-01-07 FLOW          4.0
           OVER          5.0
           STACK         6.0

【讨论】:

    【解决方案2】:

    看看here,将.reindex与MultiIndex一起使用。

    类似:

    vlr_full.reindex( pd.MultiIndex.from_product([idx, 
    "your_ticker_set"], names=['data', 'ticker']), fill_value=0)
    

    通过MultiIndex.unique(level=1)获取your_ticker_set

    【讨论】:

    • 很遗憾,没用。引发“ValueError:无法处理非唯一多索引!”。我会继续尝试调整它。
    • @RatoF 你的data 索引(例如日期)有重复的日期??
    • 有时交易不止一种资产(股票代码)。它可以在 vlr 数据框中看到(参见“2021-06-02”)。但后来我做了 vlr_full = vlr.groupby('data')。我虽然这应该在 level=0 上留下唯一的日期?这是我错了吗?
    猜你喜欢
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 2013-06-21
    • 1970-01-01
    • 2021-06-17
    • 2017-06-27
    相关资源
    最近更新 更多