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

在Pandas中重新索引多索引数据帧

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

    index1 = range(3, 7)
    index2 = range(1, 11)
    values = [np.random.random() for x in index1]
    
    df = pd.DataFrame(values, index=index1, columns=["values"])
    
    print(df)
    print(df.reindex(index2, fill_value=0))
    

    输出:

         values
    3  0.458003
    4  0.945828
    5  0.783369
    6  0.784599
          values
    1   0.000000
    2   0.000000
    3   0.458003
    4   0.945828
    5   0.783369
    6   0.784599
    7   0.000000
    8   0.000000
    9   0.000000
    10  0.000000
    

    新行的添加基于 index2 ,以及 y 0

    现在,让我们为多索引df尝试类似的方法:

    data_dict = {
        "scan": 1,
        "x": [2,3,5,7,8,9],
        "y": [np.random.random() for x in range(1,7)]
    }
    
    index1 = ["scan", "x"]
    df = pd.DataFrame.from_dict(data_dict).set_index(index)
    print(df)
    
    index2 = list(range(4, 13))
    print(df.reindex(index2, level="x").fillna(0))
    

    输出:

                   y
    scan x          
    1    2  0.771531
         3  0.451761
         5  0.434075
         7  0.135785
         8  0.309137
         9  0.838330
                   y
    scan x          
    1    5  0.434075
         7  0.135785
         8  0.309137
         9  0.838330
    

    4 )或更大(例如。, 10

    实际的数据帧有6个索引级别和几十到几百行,但我认为这段代码抓住了问题所在。我花了一点时间看 df.realign df.join ,而且我花了很多时间,但我还没有找到解决办法。如果是复制品,我道歉!

    2 回复  |  直到 6 年前
        1
  •  2
  •   Sergey    6 年前

    print(df.reindex(pd.MultiIndex.from_product([df.index.get_level_values(0).unique(), index2], names=['scan', 'x'])).fillna(0))
                    y
    scan x           
    1    4   0.000000
         5   0.718190
         6   0.000000
         7   0.612991
         8   0.609323
         9   0.991806
         10  0.000000
         11  0.000000
         12  0.000000
    
        2
  •  0
  •   Evan    6 年前

    在@Sergey的解决方法的基础上,我得到了以下结果。我扩展了这个示例,使其具有更多的级别,更紧密地复制我自己的数据。

    生成数据框:

    data_dict = {
        "sample": "A", 
        "scan": 1,
        "meas_time": datetime.now(),
        "x": [2,3,5,7,8,9],
        "y": [np.random.random() for x in range(1,7)]
    }
    
    index1 = ["sample", "scan", "meas_time", "x"]
    df = pd.DataFrame.from_dict(data_dict).set_index(index1)
    print(df)
    

    index2 = range(4, 13)
    print(df.reindex(labels=index2, level="x").fillna(0))
    

    实施Sergey的解决方案:

    df.reindex(
        pd.MultiIndex.from_product(
            [df.index.get_level_values("sample").unique(),
             df.index.get_level_values("scan").unique(),
             df.index.get_level_values("meas_time").unique(),
             index2], 
            names=["sample", "scan", "meas_time", "x"])
        ).fillna(0)
    

    .unique() 不包括,多个(产品?!?)为每个级别计算数据帧的长度。这可能是我的内核以前崩溃的原因;我没有包括 .

    这看起来很奇怪 pandas .reset_index().set_index("x").reindex("blah").set_index([list])