Python 仅使用NumPy优化步长函数的代码
我试图在下面的代码中仅使用NumPy函数(或者列表理解)来优化函数“pw” 屈服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 谢谢
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]