Python 仅使用NumPy优化步长函数的代码

Python 仅使用NumPy优化步长函数的代码,python,numpy,optimization,Python,Numpy,Optimization,我试图在下面的代码中仅使用NumPy函数(或者列表理解)来优化函数“pw” 屈服 15000 不相同的数据点。所以我似乎不知道如何使用“searchsorted” 编辑2 实际上我已经修好了: pw_func = vals[inds[inds != uu.shape[0]]] 改为 pw_func = vals[inds[inds[(inds != uu.shape[0])*(inds != 0)]-1]] 因此,至少结果数组匹配。但问题仍然在于是否有更有效的方法来实现这一点 编辑3 谢谢

我试图在下面的代码中仅使用NumPy函数(或者列表理解)来优化函数“pw”

屈服

15000
不相同的数据点。所以我似乎不知道如何使用“searchsorted”

编辑2

实际上我已经修好了:

pw_func = vals[inds[inds != uu.shape[0]]]
改为

pw_func = vals[inds[inds[(inds != uu.shape[0])*(inds != 0)]-1]]
因此,至少结果数组匹配。但问题仍然在于是否有更有效的方法来实现这一点

编辑3

谢谢田来指出错误。这个应该有用

pw_func = vals[inds[(inds != uu.shape[0])*(inds != 0)]-1]
也许更具可读性的表达方式是

non_endpts = (inds != uu.shape[0])*(inds != 0) # only consider the points in between the min/max data values
shift_inds = inds[non_endpts]-1       # searchsorted side='right' includes the left end point and not right end point so a shift is needed
pw_func = vals[shift_inds]

我想我在那些括号里迷路了!我想这就是可读性的重要性。

一个非常抽象但有趣的问题!谢谢你招待我,我玩得很开心:)

p、 我不确定您的
pw2
输出是否与
pw1
相同

参考原始
pw
s:

def pw1(x,udata):
VAL=np.arange(1,udata.shape[0]+1)。重塑(udata.shape[0],1)
pw_func=np.sum(其中(np.大于等于(x,udata)*np.小于(x,np.滚动(udata,-1)),vals,0),轴=0)
返回pw_func
def pw2(xx,uu):
inds=np.searchsorted(uu,xx,side='right')
VAL=np.arange(1,uu.shape[0]+1)
pw_func=vals[inds[inds[(inds!=uu.shape[0])*(inds!=0)]-1]]
num_mins=np.sum(xxnp.max(uu))
pw_func=np.concatenate((np.zeros(num_mins),pw_func,np.zeros(xx.shape[0]-pw_func.shape[0]-num_mins)))
返回pw_func

我的第一次尝试是利用了numpy的大量boardcasting操作:

def pw3(x,udata):
#“无”切片用于创建新轴
步骤_bool=x>=udata[None,:].T
#我们利用布尔值是1的整数值这一事实
#跳过“数据”中的最后一个值
步进VAL=np.sum(步进bool[:-1],轴=0)
#对于我们从上一步(最后一个索引)跳过的步骤
#我们把它设为zerp,这样我们就可以在到达时取消步长
#“数据”中的最后一个值
步长值[步长值[-1]]=0
返回步骤
在查看了您的
pw2
中的
searchsorted
之后,我找到了一种新的方法,可以以更高的性能使用它:

def pw4(x,udata):
inds=np.searchsorted(udata,x,side='right')
#如果x已超出数据范围,则修复最后一个数据[-1]
如果x[-1]>udata[-1]:
inds[inds==inds[-1]]=0
返回IND

与以下内容相关的绘图:

plt.plot(pw1(x,udata.reformate(udata.shape[0],1)),label='pw1')
plt.plt(pw2(x,udata),label='pw2')
plt.plt(pw3(x,udata),label='pw3')
plt.plt(pw4(x,udata),label='pw4')
使用
数据=[1,3,4,5,5,7]

使用
data=[1,3,4,5,5,7,11]

pw1
pw3
pw4
都是相同的

print(np.all(pw1(x,udata.reformate(udata.shape[0],1))==pw3(x,udata)))
>>>真的
打印(np.all(pw1(x,udata.reformate(udata.shape[0],1))==pw4(x,udata)))
>>>真的
性能:
timeit
默认运行3次,平均运行次数
number=N次)

print(timeit.Timer('pw1(x,udata.整形(udata.shape[0],1)),“from uuu main_uuu导入pw1,x,udata”)。重复(数字=1000))
>>> [3.1938983199979702, 1.6096494779994828, 1.962694135003403]
打印(timeit.Timer('pw2(x,udata)',“从主导入pw2,x,udata”)。重复(数字=1000))
>>> [0.6884554479984217, 0.6075002400029916, 0.7799002879983163]
打印(timeit.Timer('pw3(x,udata)',“从主导入pw3,x,udata”)。重复(数字=1000))
>>> [0.7369808239964186, 0.7557657590004965, 0.8088172269999632]
打印(timeit.Timer('pw4(x,udata)',“从主导入pw4,x,udata”)。重复(数字=1000))
>>> [0.20514375300263055, 0.20203858999957447, 0.19906871100101853]
pw_func = vals[inds[inds[(inds != uu.shape[0])*(inds != 0)]-1]]
pw_func = vals[inds[(inds != uu.shape[0])*(inds != 0)]-1]
non_endpts = (inds != uu.shape[0])*(inds != 0) # only consider the points in between the min/max data values
shift_inds = inds[non_endpts]-1       # searchsorted side='right' includes the left end point and not right end point so a shift is needed
pw_func = vals[shift_inds]