【问题标题】:Inserting rows in Pandas with reindex on a MultiIndex DataFrame在 MultiIndex DataFrame 上使用 reindex 在 Pandas 中插入行
【发布时间】:2018-04-21 20:24:01
【问题描述】:

我有一个大型面板数据框,其中包含多个日期的多个资产。问题是某些资产并非每天都有值,因此我希望将当天的任何空白值替换为该资产的最后一个可用值。

例如:

                       tradeDate   assetId  ticker    Sedol      price
0        2016-01-04 00:00:00.000      1786    3900  B17N9P6        1   
1        2016-01-04 00:00:00.000      2041    1898  B1JNK84        2   
2        2016-01-04 00:00:00.000      2981    CBMG  B9F9PM1        3   
3        2016-01-04 00:00:00.000      3547     MWA  B15RZR4        4   
4        2016-01-04 00:00:00.000      3570    TPLM  B065Y40        5   
5        2016-01-05 00:00:00.000      3995    MHGC  B0YRYS2        1   
6        2016-01-05 00:00:00.000      4110     DSW  B0BV2V6        2   
7        2016-01-05 00:00:00.000      4874     NWE  B03PGL4        3   
8        2016-01-05 00:00:00.000      4982    BOFI  B0637D4        4   
9        2016-01-05 00:00:00.000      5082   ISCTR  B03MYS8        5   
10       2016-01-05 00:00:00.000      5083   KCHOL  B03MVJ8        6

所以我需要对 tradeDate 和assetIds 编制索引,然后重新编制索引,以便为每个交易日期创建新行,以便始终有相同数量的assetIds。这将创建带有 NaN 的行。我对这一步感到困惑,因为我不确定使用多个索引时的语法以及tradeDate 和assetId 列不完全匹配时的语法。

最后,我将不得不用最后一个可用值替换 NaN。但是,我必须再次为tradeDate 和assetId 的两个索引执行此操作。感谢对此的帮助

【问题讨论】:

    标签: python pandas dataframe indexing


    【解决方案1】:

    TomAugspurger 巧妙地回答了您问题的第一部分here。

    基本上,您需要使用一个聪明的技巧,包括设置多索引、取消堆叠数据框、填充缺失值并再次堆叠。然后,您应该再次将填充的缺失值转换为 NaN,并使用在 pandas 中实现的 .fillna() 方法和 method='ffill',以便将 NaN 替换为最后一个可用值。

    首先,让我们生成我们需要的数据:

    import pandas as pd
    import numpy as np
    
    data =  [['2016-01-04 00:00:00.000', 1786, '3900', 'B17N9P6', 1],
    ['2016-01-04 00:00:00.000', 2041, '1898', 'B1JNK84', 2],
    ['2016-01-04 00:00:00.000', 2981, 'CBMG', 'B9F9PM1', 3],
    ['2016-01-04 00:00:00.000', 3547, 'MWA', 'B15RZR4', 4],
    ['2016-01-04 00:00:00.000', 3570, 'TPLM', 'B065Y40', 5],
    ['2016-01-05 00:00:00.000', 3995, 'MHGC', 'B0YRYS2', 1],
    ['2016-01-05 00:00:00.000', 4110, 'DSW', 'B0BV2V6', 2],
    ['2016-01-05 00:00:00.000', 4874, 'NWE', 'B03PGL4', 3],
    ['2016-01-05 00:00:00.000', 4982, 'BOFI', 'B0637D4', 4],
    ['2016-01-05 00:00:00.000', 5082, 'ISCTR', 'B03MYS8', 5],
    ['2016-01-05 00:00:00.000', 5083, 'KCHOL', 'B03MVJ8', 6]]
    
    cols  = ['tradeDate','assetId','ticker','Sedol','price']
    

    然后解决问题:

    df = pd.DataFrame.from_records(data, columns=cols)
    
    # I used `-1` to fill the empty values, but use whatever value
    # does not occur in the dataset
    df = df.set_index(['tradeDate', 'assetId']).unstack().fillna(-1).stack()
    
    # Once you have the data frame stacked again, you need to
    # convert unknown values to np.nan again
    df.replace(-1, np.nan, inplace=True)
    
    # Fill with latest value for given assetId
    df = df.groupby(level=['assetId']).fillna(method='ffill')
    

    希望这个答案能涵盖您的问题,否则请告诉我们。

    【讨论】:

    • 非常感谢!这正是我需要的,不知道堆栈功能。 ffill 是我需要向前填充的,一件事是我不想包含在开始日期根本不可用的资产(例如,IPO 或其他东西)。所以这个方法仍然显示无法前向填充的资产的 NA,这意味着没有初始后向值要填充。这意味着如果我不想在资产首次交易之前查看资产,我应该删除带有 NAs 的行——对吗?再次感谢!!
    • 没错。通过这种方法,您将在给定资产的首次交易/首次公开募股之前的任何日期获得 NaN。所以你只需要删除这些行,例如使用.dropna() 方法。
    猜你喜欢
    • 2019-05-24
    • 2020-11-13
    • 1970-01-01
    • 2013-01-22
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多