比较两个数据框,然后根据另一个将新列添加到其中一个数据框

时间:2019-07-24 19:41:59

标签: python pandas numpy

我需要能够比较两个数据帧,一个比较一列,一个比较两列,像这样:

import numpy as np
import pandas as pd

df_1 = pd.DataFrame(columns=list('AB'))
df_1['A'] = np.random.randint(00,99,size=(5))

df_2  = pd.DataFrame(columns=list('XY'))
df_2['X'] = np.arange(0,100,0.1)
df_2['Y'] = np.cos(df_2['X']) + 30

现在,我想比较df_1 ['A']和df_2 ['X']来找到匹配的值,然后在df_1中创建第二列(aka df_1 ['B']),并使用df_2 [与匹配的df_2 ['X']值相对应的'Y']。有人有解决方案吗?

如果数据帧的前两列之间没有完全匹配的值,是否有办法匹配下一个最接近的值(阈值约为5%)?

2 个答案:

答案 0 :(得分:1)

如OP中所述,如果df_2 ['X']中不存在完全匹配的内容,您可能还希望捕获与df_1 ['A']列表最接近的值...为此,您可以尝试以下操作:

根据OP定义df:

df_1 = pd.DataFrame(columns=list('AB'))
df_1['A'] = np.random.randint(00,99,size=(5))

df_2  = pd.DataFrame(columns=list('XY'))
df_2['X'] = np.arange(0,100,0.1)
df_2['Y'] = np.cos(df_2['X']) + 30 #changed "line_x"

首先定义一个将找到最接近值的函数:

import numpy as np    
def find_nearest(df, in_col, value, out_col): #args = input df (df_2 here), column to match against ('X' here), value to match in in_col (values in df_1['A'] here), column with data you want ('Y' here)
    array = np.asarray(df[in_col])
    idx = (np.abs(array - value)).argmin()
    return df.iloc[idx][out_col]

然后获取您想要的所有df_2 ['Y']值:

matching_vals=[] #declare empty list of matching values from df_2['Y'] to add to df_1['B']
for A in df_1['A'].values: #loop through all df_1['A'] values
    if A in df_2['X']: # if exact match
        matching_vals.append(float(df_2[df_2['X']==A]['Y'])) #append corresponding df_2['Y'] value to list
    else: #no exact match
        matching_vals.append(find_nearest(df_2,'X',A,'Y')) #append df_2['Y'] value with closest match in df_2['X'] column

最后,将其添加到原始df_1:

df_1['B']=matching_vals

此示例适用于您提供的df,但是您可能不得不稍微花一些时间来处理真实数据...

如果要强制执行5%阈值规则,还可以再添加一个if语句。如果不通过,只需将nan附加到列表中(或最适合您的方法)

答案 1 :(得分:0)

df_2.merge(df_1, left_on=['X'], right_on=['A']).rename({'Y':'B', axis='columns')

合并过滤器,将df_1['A']df_2['X']之间的公用值以及将“ Y”重命名为“ B”之后。