代码之家  ›  专栏  ›  技术社区  ›  Felix

强制显示索引值

  •  1
  • Felix  · 技术社区  · 6 年前

    我想从数据帧构造一个时间序列。它是多索引的,在一个索引中的每一个移动都对应于一个恒定的时间偏移。然而,这些指数并非都存在。我如何扩展数据(用于未来填充或其他插补),使某些级别的指数被迫具有其所有值?

    # Example: here I0 is a running number and I1 to be forced to have 0 and 1 for every I0.
    
    I0 | I1 || Value     ->    I0 | I1 || Value
    ---+----++-------          ---+----++-------
     0 |  0 ||   1              0 |  0 ||   1
       |  1 ||   2                |  1 ||   2
     1 |  0 ||   3              1 |  0 ||   3
     2 |  0 ||   5                |  1 ||   NaN
       |  1 ||   6              2 |  0 ||   5
     3 |  1 ||   8                |  1 ||   6
                                3 |  0 ||   NaN
                                  |  1 ||   8
    

    df = pd.DataFrame({'I0': [0,0,1,2,2,3], 'I1': [0,1,0,0,1,1], 'Value': [1,2,3,5,6,8]})
    df = df.set_index(['I0', 'I1'])
    

    澄清

    我有数据帧的形式,索引已经设置好了。在最好的情况下,我希望能够操纵MultiIndex,这样就不必将级别转换回列。但如果需要的话我理解。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Felix    6 年前

    使用 MultiIndex.from_product 具有 Series.reindex :

    df = pd.DataFrame({'I0': [0,0,1,2,2,3], 'I1': [0,1,0,0,1,1], 'Value': [1,2,3,5,6,8]})
    
    mux = pd.MultiIndex.from_product([df['I0'].unique(), [0,1]], names=['I0','I1'])
    

    mux = pd.MultiIndex.from_product([np.arange(df['I0'].max() + 1), 
                                      df['I1'].unique()], 
                                      names=['I0','I1'])
    

    mux = pd.MultiIndex.from_product([df['I0'].unique(), df['I1'].unique()], names=['I0','I1'])
    df = df.set_index(['I0', 'I1']).reindex(mux)
    
    print (df)
           Value
    I0 I1       
    0  0     1.0
       1     2.0
    1  0     3.0
       1     NaN
    2  0     5.0
       1     6.0
    3  0     NaN
       1     8.0
    

    在一些讨论解决方案被更改之后—为了保留多索引的其他级别,首先需要将级别转换为整数(以避免作为字符串排序),然后使用 unstack 具有 stack . 保存 NaN 使用参数 dropna=False :

    a = df.index.get_level_values(0).astype(int)
    b = df.index.get_level_values(1).astype(int)
    c = df.index.get_level_values(2)   # String index level
    d = df.index.get_level_values(3).astype(int)
    
    df.index = pd.MultiIndex.from_arrays([a, b, c, d], names=df.index.names)
    
    df = df.unstack().stack(dropna=False)