用 Numpy 或 Pandas 在 Python 中找到整数可以驻留的最接近边界值对

Find the closest boundries value pair that an integer can reside with Numpy or Pandas in Python

给定一维 array

a=np.array([ 65, 251, 431])

和另一个 1D array 用于构造边界。

b=np.array([  4,  10,  18,  22,  28,  33,  40,  49,  72,  83,  90,  93,  99,
              107, 113, 119, 130, 142, 161, 167, 173, 178, 183, 196, 202, 209,
              215, 221, 228, 233, 240, 258, 262, 269, 274, 281, 286, 297, 311,
              317, 352, 354, 358, 365, 371, 376, 382, 389, 396, 413, 420, 441,
              443, 450, 459, 467, 473, 477, 483, 491, 495, 497])

例如两点边界坐标可以是4,10,4,18,4,497,...,495,497.

objective就是求一个整数(例如数组a中的每一个整数)可以所在的最近边界值对

例如值65,它可以驻留的最近边界是49,72

下面的代码应该回答 objective

import numpy as np
import pandas as pd
a=np.array([ 65, 251, 431])

# Assumed `b` is sorted from lowest to highest value and no duplicate values
b=np.array([  4,  10,  18,  22,  28,  33,  40,  49,  72,  83,  90,  93,  99,
              107, 113, 119, 130, 142, 161, 167, 173, 178, 183, 196, 202, 209,
              215, 221, 228, 233, 240, 258, 262, 269, 274, 281, 286, 297, 311,
              317, 352, 354, 358, 365, 371, 376, 382, 389, 396, 413, 420, 441,
              443, 450, 459, 467, 473, 477, 483, 491, 495, 497])


leadB =b[:-1]
trailB=b[1:]

all_val=[]
for dis_a in a:
    for l,t in zip(leadB,trailB):
        if l < dis_a <= t:
            all_val.append({'a':dis_a,'lb':l,'tb':t})

# The final output can be in the form of pandas or numpy array
df=pd.DataFrame(all_val)

但是,上述方法严重依赖于两个阶段for-loop。我想知道是否有使用 NumpyPandas.

的内置函数执行此操作的有效方法

这似乎是使用 np.searchsorted 的理想问题,但根据您的实际要求,可能有两种可能的解决方案:

  • 如果a中的所有元素都保证落在边界点之间:
i = np.searchsorted(b, a)
df = pd.DataFrame({'a': a, 'lb': b[i - 1], 'tb': b[i]})
  • 如果 a 的某些元素不落在边界点内,则更通用的解决方案是:
i = np.searchsorted(b, a)
m = ~np.isin(i, [0, len(b)])

df = pd.DataFrame({'a': a})
df.loc[m, 'lb'], df.loc[m, 'tb'] = b[i[m] - 1], b[i[m]]

结果

     a   lb   tb
0   65   49   72
1  251  240  258
2  431  420  441