首页 > 解决方案 > Vlook Up Elements from another dataframe 用于在 Python 中创建 MultiIndex DataFrame

问题描述

有 2 个数据框和一个分层索引(pandas multiIndex)。数据框 A 有一个 ID 和名称列表。数据框 B 有一个名称组合列表和一个相似度分数。

我想基于多索引从数据帧 A 中获取值并检查数据帧 B 中是否存在该组合。如果是,我想为我的 Multindex 数据帧带来相似度分数,否则只有 0。

数据帧 A(原始数据帧)

test= pd.DataFrame({'row':['a','b','c','d'],'col_A' : ["Alexis","Alexi","Peter","Pete"]})

test = test.set_index('row');test
Out:   
    row   col_A   
    a     Alexis
    b     Alexi
    c     Peter
    d     Pete

DataFrame B(名称相似性)

names = pd.DataFrame({'A' : ["Alexis","Alexi","Peter","Pete"]
                    ,'B' : ["Alexi","Alexis","Pete","Peter"]
                    , "similarity" : [0.9,0.9,0.8,0.8]})
Out:
       A       B      similarity
0   Alexis   Alexi         0.9
1   Alexi    Alexis        0.9
2   Peter    Pete          0.8
3   Pete     Peter         0.8

多索引

# Creating a Pandas MultiIndex 
arrays = [['a', 'a', 'a', 'b', 'b', 'c'],
          ['b', 'c', 'd', 'c', 'd', 'd']]

tuples = list(zip(*arrays))
indexy = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

遍历索引我使用下面的函数,但是,我不知道如何调整它,以便在存在时带来相似度得分,或者在不存在时带来 0。

a = pd.DataFrame((test.reindex(indexy.get_level_values(0)).values (?) test.reindex(indexy.get_level_values(1))).values,index=indexy,columns=test.columns)

我想看起来像这样:

   row      similarity
first second           
a     b             0.9
      c             0
      d             0
b     c             0
      d             0
c     d             0.8

标签: pandasindexinghierarchical

解决方案


因此,如果您对多索引不太感兴趣,这是一种按预期获取数据的方法:

import pandas as pd
test= pd.DataFrame({'row':['a','b','c','d'],'col_A' : ["Alexis","Alexi","Peter","Pete"]})
names = pd.DataFrame({'A' : ["Alexis","Alexi","Peter","Pete"],
                    'B' : ["Alexi","Alexis","Pete","Peter"],
                    "similarity" : [0.9,0.9,0.8,0.8]})

注意我没有set_index test,但你可以这样做,它会稍微改变以下内容(见评论)。您可以创建a数据框,例如:

import itertools
a = pd.DataFrame([p for p in itertools.combinations(test['col_A'], 2)],columns =['A','B'],
                 index=['%s,%s'%p for p in itertools.combinations(test['row'], r=2)])
# here if you did set_index your test, then replace 
# index=['%s,%s'%p for p in itertools.combinations(test['row'], r=2)] by 
# index=['%s,%s'%p for p in itertools.combinations(test.index, r=2)]

它看起来像:

          A      B
a,b  Alexis  Alexi
a,c  Alexis  Peter
a,d  Alexis   Pete
b,c   Alexi  Peter
b,d   Alexi   Pete
c,d   Peter   Pete

然后,您可以在 A 和 B 列上使用reset_index(将当前索引作为列获取,但这取决于您想要的确切内容) ,merge用0names填充nan,删除 A 和 B 两列,然后重命名(如有必要):

a = a.reset_index().merge(names, how = 'left', on = ['A','B']).fillna(0).\
     drop(labels = ['A','B'], axis=1).rename(columns = {'index':'row', 'similarity':'col_A'})

让我知道你是否可以做你想做的事

编辑:使用您寻找的新输出,您可以执行以下操作:

a = pd.DataFrame([p for p in itertools.combinations(test['col_A'], 2)],columns =['A','B'],
                 index=pd.MultiIndex.from_tuples([p for p in itertools.combinations(test.index, r=2)], names=['first', 'second']))

注意:itertools生成用于pd.MultiIndex.from_tuples定义多索引 DF 的元组。

现在你可以merge(为了保持多索引,你需要reset_index之前和set_index之后:

a = a.reset_index().merge(names, how = 'left', on = ['A','B']).fillna(0).\
         drop(labels = ['A','B'], axis=1).set_index(['first', 'second'])

推荐阅读