匹配两个不同长度的数据帧中的最近值

Matching nearest values in two dataframes of different lengths

如果我有两个不同长度、不同标签和不同数字精度级别的数据帧,如下所示:

df1 = pd.DataFrame({'a':np.array([1.2345,2.2345,3.2345]),'b':np.array([4.123,5.123,6.123])})
df2 = pd.DataFrame({'A':np.array([1.2346,2.2343]),'B':np.array([4.1232,5.1239])})

如何找到两个数据帧在 'a' 和 'A' 列之间具有近似匹配值的行(比如在 2 位精度内),从而产生这样的数据帧

      a         b         A         B
------------------------------------------------
 | 1.2345  |  4.123  |  1.2346  |  4.1232  |
 | 2.2345  |  5.123  |  2.2343  |  5.1239  |

尝试次数:

尝试 #1:

matches_df = pd.merge(df1, df2,  how='inner', left_on=['a'], right_on = ['A'])

这仅在 'a' 和 'A' 列之间存在完全匹配的情况下有效,但我不确定如何合并一个软糖因子以允许匹配精度在 2 位数字以内的行。

尝试 #2

matches_df = df1.loc[np.round(df1['a'],2)==np.round(df2['A'],2)]

这给出了错误“ValueError:只能比较相同标记的系列对象”,因为我认为两个数据帧有不同的标签('a','b' 和 'A','B').

关于如何实现这一点有什么想法吗?

使用KDTree,你可以在m O(log n)中找到最接近df1的数学,其中ndf2m df1.

中的元素数
import pandas as pd
import numpy as np
from scipy.spatial import cKDTree

df1 = pd.DataFrame({'a':np.array([1.2345,2.2345,3.2345]),'b':np.array([4.123,5.123,6.123])})
df2 = pd.DataFrame({'A':np.array([1.2346,2.2343]),'B':np.array([4.1232,5.1239])})


def spatial_merge_NN(df1, df2, xyz=['A', 'B']):
    ''' Add features from df2 to df1, taking closest point '''
    tree = cKDTree(df2[xyz].values)
    dists, indices = tree.query(df1[['a','b']].values, k=1)
    fts = [c for c in df2.columns]
    for c in fts:
        df1[c] = df2[c].values[indices]
    return df1

df_new = spatial_merge_NN(df1, df2, ['A', 'B'])
#         a      b       A       B
# 0  1.2345  4.123  1.2346  4.1232
# 1  2.2345  5.123  2.2343  5.1239
# 2  3.2345  6.123  2.2343  5.1239

它放置一个数据帧常量(在本例中为 df1)并遍历 df2 并从 d2 中找到最接近的对并添加该行。