来自不规则长度列表的MultiIndex

问题描述 投票:4回答:3

我有一个列表清单,我想将其制作成多索引熊猫数据框,然后将其合并到原始熊猫数据框。列表的每一行包含一个观察值,列表中的值包含与该观察值匹配的相应行。

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

原始数据框的格式如下:

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
3个回答
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

1
投票

您可以使用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

1
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.