用 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
。我想知道是否有使用 Numpy
或 Pandas
.
的内置函数执行此操作的有效方法
这似乎是使用 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
给定一维 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
。我想知道是否有使用 Numpy
或 Pandas
.
这似乎是使用 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