【问题标题】:MultiIndex from lists of lists with irregular lengthMultiIndex 来自不规则长度的列表
【发布时间】:2020-03-15 07:48:20
【问题描述】:

我有一个列表列表,我想将其制成多索引 pandas 数据框,然后我可以将其合并到原始 pandas 数据框。列表的每一行都包含一个观察值,列表中的值由与该观察值匹配的相应行组成。

这是我所拥有的一个简单版本:

原始数据框格式如下:

original=(pd.DataFrame([['JFK','New York, NY'],['EWR','Newark, NJ'],
                        ['BWI','Baltimore, MD'],['PHL','Philadelphia, PA'],
                        ['DCA','Washington, DC']],columns=['ID','City']))
original
    ID              City
0  JFK      New York, NY
1  EWR        Newark, NJ
2  BWI     Baltimore, MD
3  PHL  Philadelphia, PA
4  DCA    Washington, DC

匹配输出(将位置与一定半径内的其他位置匹配)是一个列表列表,如下所示:

matches=[[0],[1,3],[2],[1,3],[4]]
matches
[[0], [1, 3], [2], [1, 3], [4]]

这是我想要的样子:

              ID              City
Org Match
0   0        JFK      New York, NY
1   1        EWR        Newark, NJ 
    3        PHL  Philadelphia, PA 
2   2        BWI     Baltimore, MD
3   1        EWR        Newark, NJ
    3        PHL  Philadelphia, PA
4   4        DCA    Washington, DC

我知道如何加入多索引级别,但不知道如何正确设置多索引。最终,这将需要大规模进行。也乐于以不同的方式接近。

根本问题是将位置与给定距离内的所有其他位置匹配。这是在一个单独的模块中完成的,输出是上面引用的列表列表。

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    我会构建索引,与originalset_index 合并:

    ret = (pd.concat(pd.DataFrame({'Org':i, 'Match':v}) for i,v in enumerate(matches))
             .merge(original, left_on='Match', right_index=True, how='left')
             .set_index(['Org','Match'])
          )
    

    输出:

                ID              City
    Org Match                       
    0   0      JFK      New York, NY
    1   1      EWR        Newark, NJ
        3      PHL  Philadelphia, PA
    2   2      BWI     Baltimore, MD
    3   1      EWR        Newark, NJ
        3      PHL  Philadelphia, PA
    4   4      DCA    Washington, DC
    

    【讨论】:

      【解决方案2】:

      你可以使用concat:

      matches = [[0], [1, 3], [2], [1, 3], [4]]
      
      result = pd.concat([df.iloc[match] for match in matches], keys=list(range(len(matches))), names=['Org', 'Match'])
      
      print(result)
      

      输出

                  ID              City
      Org Match                       
      0   0      JFK      New York, NY
      1   1      EWR        Newark, NJ
          3      PHL  Philadelphia, PA
      2   2      BWI     Baltimore, MD
      3   1      EWR        Newark, NJ
          3      PHL  Philadelphia, PA
      4   4      DCA    Washington, DC
      

      【讨论】:

        【解决方案3】:

        matches 构造一个系列并使用explode 获取用于reindexset_index 的值。最后swaplevel

        s = pd.Series(matches).explode()
        df = original.reindex(s).set_index(s.index, append=True).swaplevel(1,0)
        
        Out[54]:
              ID              City
        0 0  JFK      New York, NY
        1 1  EWR        Newark, NJ
          3  PHL  Philadelphia, PA
        2 2  BWI     Baltimore, MD
        3 1  EWR        Newark, NJ
          3  PHL  Philadelphia, PA
        4 4  DCA    Washington, DC
        

        或者你可以构造多索引并将其用于reindexset_index,并重新排序最终df的多索引顺序

        ix = pd.MultiIndex.from_tuples([(i, y) for i, x in enumerate(matches) for y in x])
        df = original.reindex(ix.get_level_values(1)).set_index(ix.get_level_values(0), append=True).swaplevel(1,0) 
        
        Out[43]:
              ID              City
        0 0  JFK      New York, NY
        1 1  EWR        Newark, NJ
          3  PHL  Philadelphia, PA
        2 2  BWI     Baltimore, MD
        3 1  EWR        Newark, NJ
          3  PHL  Philadelphia, PA
        4 4  DCA    Washington, DC
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-27
          • 2020-12-31
          相关资源
          最近更新 更多