在pandas中将一个数据框的索引值映射到另一个数据框

4

我有一个名为df_in的数据框,格式如下:

import pandas as pd
import numpy as np
dic_in = {'A':['A1','A1','A1','L3','A3','A3','B1','B1','B1','B2','A2'],
       'B':['xxx','ttt','qqq','nnn','lll','nnn','eee','xxx','qqq','bbb','sss'],
       'C':['fas','efe','pfo','scs','grj','rpo','cbb','asf','asc','wq3','mls']}
df_in = pd.DataFrame(dic_in)

我还有另一个数据框,名为df_map:

dic_map = {'X':['A1' ,'A1' ,'A1' ,'A2' ,'A3' ,'B1' ,'B1' ,'B1' ,'B1' ,'B2' ,'B3' ,'B3' ,'L1', 'L3' ,'L3'],
           'Y':['qqq','ttt','xxx','sss','lll','eee','qqq','xxx','zzz','bbb','mmm','ooo','kkk','nnn','ttt']}
df_map = pd.DataFrame(dic_map)

我的目标是研究df_in中每一个row[['A','B']];如果这对项目在df_map中被识别,则我将提取相应索引的值,并将其设置到第一个数据框的另一列中。
例如:假设在0中找到了一对A1-xxx,那么我将在A1-xxx旁边放置一个0。 如果找不到一对,则我将放置NaN
结果应该如下所示:
    Idx   A    B    C
0     2  A1  xxx  fas
1     1  A1  ttt  efe
2     0  A1  qqq  pfo
3    13  L3  nnn  scs
4     4  A3  lll  grj
5   NaN  A3  nnn  rpo
6     5  B1  eee  cbb
7     7  B1  xxx  asf
8     6  B1  qqq  asc
9     9  B2  bbb  wq3
10    3  A2  sss  mls

你能给我建议一个聪明高效的方式来达到我的目标吗?

1个回答

4

您可以使用mergereset_index,然后使用drop删除列:

print (pd.merge(df_in, 
                df_map.reset_index(), 
                left_on=['A','B'], 
                right_on=['X','Y'], 
                how='left').drop(['X','Y'], axis=1))

     A    B    C  index
0   A1  xxx  fas    2.0
1   A1  ttt  efe    1.0
2   A1  qqq  pfo    0.0
3   L3  nnn  scs   13.0
4   A3  lll  grj    4.0
5   A3  nnn  rpo    NaN
6   B1  eee  cbb    5.0
7   B1  xxx  asf    7.0
8   B1  qqq  asc    6.0
9   B2  bbb  wq3    9.0
10  A2  sss  mls    3.0

感谢Julien Marrec提供的另一种解决方案:

df_in.merge(df_map.reset_index()
                  .set_index(['X','Y']), 
            left_on=['A','B'], 
            right_index=True, 
            how='left')

最后,如果想要更改列的顺序:
df = pd.merge(df_in, 
              df_map.reset_index(), 
              left_on=['A','B'], 
              right_on=['X','Y'], 
              how='left').drop(['X','Y'], axis=1)
cols = df.columns[-1:].tolist() + df.columns[:-1].tolist()
print (cols)
['index', 'A', 'B', 'C']

df = df[cols]
print (df)
    index   A    B    C
0     2.0  A1  xxx  fas
1     1.0  A1  ttt  efe
2     0.0  A1  qqq  pfo
3    13.0  L3  nnn  scs
4     4.0  A3  lll  grj
5     NaN  A3  nnn  rpo
6     5.0  B1  eee  cbb
7     7.0  B1  xxx  asf
8     6.0  B1  qqq  asc
9     9.0  B2  bbb  wq3
10    3.0  A2  sss  mls

1
你比我快,我想到了 df_in.merge(df_map.reset_index().set_index(['X','Y']), left_on=['A','B'], right_index=True, how='left') - Julien Marrec
如果我想在操作期间将索引向右移动1个位置,以使映射的索引值全部+1,该怎么办? - Federico Gentile
你所说的“移动索引”,是指在合并后执行 df['index'] += 1 吗? - Julien Marrec
还是之前的合并方式?例如 shifted = df_map.reset_index() 然后进行移位操作 shifted['index'] = shifted['index'].shift(),最后执行合并操作df = pd.merge(df_in, shifted, left_on=['A','B'], right_on=['X','Y'], how='left').drop(['X','Y'], axis=1) - jezrael
我在考虑可能在合并期间完成它...如果不可能的话,我认为在之前完成会更好。 - Federico Gentile
我认为可以使用merge not,但在它之前或之后也是可能的。之前可以像这样:shifted = df_map.reset_index() shifted['index'] += 1,之后同样的方式。 - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接