matlab 二分查找,numpy二分查找 - osc_g2u21ncv的个人空间 - OSCHINA - 中文开源技术交流社区...

a = np.array([1, 2, 2, 3])

print(np.searchsorted(a, 0)) # 0

print(np.searchsorted(a, 1)) # 0

print(np.searchsorted(a, 2)) # 1

print(np.searchsorted(a, 2, 'left')) # 1

print(np.searchsorted(a, 2, 'right')) # 3

print(np.searchsorted(a, 2.5, 'right')) # 3

print(np.searchsorted(a, 2.5, 'left')) # 3

print(np.searchsorted(a, 3, 'left')) # 3

print(np.searchsorted(a, 3, 'right')) # 4

print(np.searchsorted(a, 4)) # 4

print(np.searchsorted(a, [0, 1, 2, 3, 4, 5, ])) # [0 0 1 3 4 4]

searchsorted有三个重要参数:

a:待查找的有序数组

v:待查找的值

side:字符串,取值为left或者right,表示取下界(闭区间)还是取上界(开区间),默认参数为下界闭区间

利用searchsorted可以非常炫酷地实现轮盘赌随机选取:

t = np.cumsum(weights)

sample = np.searchsorted(t, np.random.random() * t[-1])

cumsum保证了递增,searchsorted二分查找,其中t[-1]表示全部元素之和,整个过程一气呵成、美不胜收。 虽然如此,这种方式依然不是最好的方法。因为numpy提供了轮盘赌算法。

from collections import Counter

import numpy as np

a = []

for i in range(10000):

x = np.random.choice([1, 2, 3], 2, p=[0.1, 0.3, 0.6])

a.extend(x)

a = Counter(a)

a = np.array([np.array(i) for i in a.items()], dtype=np.float32)

a[:, 1] /= np.sum(a[:, 1])

print(a)

输出为

[[1. 0.0993 ]

[2. 0.30325]

[3. 0.59745]]

因为searchsorted的下闭区间、上开区间效果有些奇特,所以可以wrap一下使它的行为更加明确

二分查找实际上可以写成四种:

左闭区间

右闭区间

左开区间

右开区间

如果自己写,一定要十分小心地考虑好边界条件才能够避免出错。

import numpy as np

def bisearch(a, v, can_eq=True, side='left'):

x = np.searchsorted(a, v, side=side)

if x >= a.shape[0]:

return x

if can_eq:

if side == 'left':

if a[x] == v:

return x

else:

return x - 1

else:

if a[x] > v:

if x > 0 and a[x - 1] == v:

return x - 1

else:

return x

else:

return x

else:

if side == 'left':

if a[x] == v:

return x - 1

else:

return x

else:

return x

a = np.array([1, 2, 2, 4])

print(bisearch(a, 2, True, 'left'))#1

print(bisearch(a, 2, True, 'right'))#2

print(bisearch(a, 2, False, 'left'))#0

print(bisearch(a, 2, False, 'right'))#3

print(bisearch(a, -1, True, 'left'))#-1

print(bisearch(a, 5, True, 'right'))#4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值