python - Pandas:对于排序系列 B 的所有元素,查找排序系列 A 中最接近元素的索引

标签 python pandas algorithm

我有一个数据框,其中有两列排序的整数。

      A        B
0     17       15
1     18       18
2     19       20
3     20       21
4     22       21
5     23       27

对于B的所有元素,我想找到A的最接近匹配元素的索引:

      A        B       closest_match_idx
0     17       15      0
1     18       18      1
2     19       20      3
3     20       21      3
4     22       21      3
5     23       27      5

我知道我能做到

df['closest_match_idx'] = df.B.map(lambda x: (df.A - x).abs().idxmin()))

但这对于显然是 O(N) 的问题来说是一个 O(N**2) 解决方案。除了滚动我自己的索引查找函数之外,我找不到任何更好的解决方案,但这感觉像是一个已有解决方案的问题。有想法吗?

就上下文而言,我最终想做的是在 A 中为 B 的每个元素找到最接近的匹配元素,最大绝对差值达到最大(否则仅使用 B 中的值):

match_diff = df.B - df.A.iloc[df['closest_match_idx']]
df['output'] = B
replace_idxs = np.where(diff.abs() <= 2)
df['output'].iloc[replace_idxs] = df['A'].iloc[replace_idxs]

searchsorted or this index trick已经差不多了,但还没有完全实现。

      A        B       closest_match_idx   match_diff    output
0     17       15      0                   2             17
1     18       18      1                   0             18
2     19       20      3                   1             20
3     20       21      3                   1             20
4     22       21      3                   1             20
5     23       27      5                   4             23

我还应该注意到,在我的示例中,A 和 B 具有相同的长度,但我想要一个可以推广到一系列不同长度的解决方案。

最佳答案

您可以使用merge_asof 。这需要对帧进行排序。这样做的好处是它支持 tolerance 参数,允许您指定考虑匹配的卡尺。

我将保留附加的'A_match'列,但如果您不需要它,可以将其删除。

res = pd.merge_asof(df.sort_values('B'), 
                    df.rename_axis(index='closest_idx').reset_index().drop(columns='B').sort_values('A'),
                    left_on='B', right_on='A',
                    direction='nearest',
                    suffixes=['', '_match'])

print(res)

    A   B  closest_idx  A_match
0  17  15            0       17
1  18  18            1       18
2  19  20            3       20
3  20  21            3       20
4  22  21            3       20
5  23  27            5       23

设置|距离|的容差<= 1

res = pd.merge_asof(df.sort_values('B'), 
                    df.rename_axis(index='closest_idx').reset_index().drop(columns='B').sort_values('A'),
                    left_on='B', right_on='A',
                    direction='nearest',
                    suffixes=['', '_match'],
                    tolerance=1)

#    A   B  closest_idx  A_match
#0  17  15          NaN      NaN
#1  18  18          1.0     18.0
#2  19  20          3.0     20.0
#3  20  21          3.0     20.0
#4  22  21          3.0     20.0
#5  23  27          NaN      NaN

关于python - Pandas:对于排序系列 B 的所有元素,查找排序系列 A 中最接近元素的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66162447/

相关文章:

python - 使用 pandas 按列值分组条形图

string - 将字符串转换为插入次数最少的回文

python - 在 Python 中使用 SymPy 计算表达式

python - pandas python 中数据帧的随机行会带来不同的回归结果?

python - Caffe 中的预测 - 异常 : Input blob arguments do not match net inputs

python - Pandas 的自定义财政季度?

algorithm - Racket 上的动态规划

algorithm - 给定二维点列表,找到最接近所有其他点的点

python - 如何在字典中分配函数?

python - 如何将 py 制作的 exe 文件从我的电脑更新到我发送给它的人?