合并pandas数据帧时如何保留列多索引值

2024-07-05 11:12:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个pandas数据帧,如下所示:

df1 = pd.DataFrame({('Q1', 'SubQ1'):[1, 2, 3], ('Q1', 'SubQ2'):[1, 2, 3], ('Q2', 'SubQ1'):[1, 2, 3]})
df1['ID'] = ['a', 'b', 'c']

df2 = pd.DataFrame({'item_id': ['a', 'b', 'c'], 'url':['a.com', 'blah.com', 'company.com']})

df1

^{pr2}$

df2

  item_id          url
0       a        a.com
1       b     blah.com
2       c  company.com

请注意,df1有一些列具有层次索引(例如('Q1', 'SubQ1')),有些列只有普通索引(例如ID)。在

我想合并IDitem_id字段上的这两个数据帧。使用:

result = pd.merge(df1, df2, left_on='ID', right_on='item_id')

给出:

   (Q1, SubQ1)  (Q1, SubQ2)  (Q2, SubQ1) (ID, ) item_id          url
0            1            1            1      a       a        a.com
1            2            2            2      b       b     blah.com
2            3            3            3      c       c  company.com

如您所见,合并本身运行良好,但MultiIndex已丢失,并已恢复为元组。我尝试使用pd.MultiIndex.from_tuples重新创建多重索引,如:

result.columns = pd.MultiIndex.from_tuples(result)

但是这会导致item_idurl列的问题,它们只使用名称的前两个字符:

     Q1          Q2 ID  i            u
  SubQ1 SubQ2 SubQ1     t            r
0     1     1     1  a  a        a.com
1     2     2     2  b  b     blah.com
2     3     3     3  c  c  company.com

df2中的列转换为一个元素元组(即('item_id',)而不仅仅是'item_id')没有任何区别。在

如何合并这两个数据帧并正确保存多重索引?或者,我如何获得merge的结果并返回到具有正确多重索引的列,而不会混淆item_id和{}列的名称?在


Tags: 数据comidurlitemcompanypddf1
2条回答

ID的列不是“非层次结构”。它用('ID', )表示。但是,pandas允许您只引用第一级列,这种方式看起来就像是在引用一个单级列结构。这意味着df1['ID']和{}以及{}一样有效。但是如果顶层'ID'在第二层有更多的列与之关联,df1['ID']将返回一个数据帧。我觉得这个解决方案更合适,它看起来很像@JohnGalt在评论中的回答。在

df1.assign(u=df1[('ID', '')].map(df2.set_index('item_id').url))

     Q1          Q2 ID            u
  SubQ1 SubQ2 SubQ1                
0     1     1     1  a        a.com
1     2     2     2  b     blah.com
2     3     3     3  c  company.com

将一个单级列数据帧连接到多级列数据帧是很困难的。我不得不人为地增加一个级别。在

^{pr2}$

如果你不能打败他们,那就加入他们。(在合并之前使两个数据帧具有相同数量的索引级别):

import pandas as pd

df1 = pd.DataFrame({('Q1', 'SubQ1'):[1, 2, 3], ('Q1', 'SubQ2'):[1, 2, 3], ('Q2', 'SubQ1'):[1, 2, 3]})
df1['ID'] = ['a', 'b', 'c']

df2 = pd.DataFrame({'item_id': ['a', 'b', 'c'], 'url':['a.com', 'blah.com', 'company.com']})

df2.columns = pd.MultiIndex.from_product([df2.columns, ['']])
result = pd.merge(df1, df2, left_on='ID', right_on='item_id')
print(result)

收益率

^{pr2}$

这也避免了UserWarning

pandas/core/reshape/merge.py:551: UserWarning: merging between different levels can give an unintended result (2 levels on the left, 1 on the right)

相关问题 更多 >