我对numpy很新。我有以下代码,它给了我想要的结果:
import numpy as np
def get_result(S,K,delS):
res=np.zeros(S.shape[0],dtype=np.float64)
for j in range(res.shape[0]):
if S[j]-K>delS:
res[j]+=np.floor((S[j]-K)/delS)
K+=np.floor((S[j]-K)/delS)*delS
elif S[j]-K<-delS:
res[j]+=np.ceil((S[j]-K)/delS)
K+=np.ceil((S[j]-K)/delS)*delS
return res
S=np.array([1.0,1.05,1.1,1.12,1.09,1.14,1.21,1.6,1.05,1.0,0.95,0.90,0.87,0.77,0.63,0.85,0.91,0.76],dtype=np.float64)
K=1.0
delS=0.1
l=get_result(S,K,delS)
for j in range(S.shape[0]):
print("%d\t%.2f\t%.0f" % (j,S[j],l[j]))
get_result函数包含一个for循环,因此对于较大的输入向量S来说速度很慢。这样的函数可以用numpy语法进行矢量化吗?任何帮助将不胜感激。
答案 0 :(得分:1)
在数组或计算中处理2个或更多条件时的一般模式是构造一个布尔掩码,并对该掩码为真的元素采取一个动作,并在假的情况下采用不同的行为:
res=np.zeros(S.shape[0],dtype=np.float64)
mask - S-K>delS
res[mask] = ...S[mask]
res[~mask] = ...S[~mask]
变体是使用np.where(mask)
来识别索引。
但似乎使您的计算复杂化的是测试不断变化。也就是说,K
的{{1}}来自j+1
的计算。
j
为了处理这种迭代,我们通常会尝试使用for j in range(res.shape[0]):
if S[j]-K>delS:
res[j]+=np.floor((S[j]-K)/delS)
K+=np.floor((S[j]-K)/delS)*delS
elif S[j]-K<-delS:
res[j]+=np.ceil((S[j]-K)/delS)
K+=np.ceil((S[j]-K)/delS)*delS
或其他累积np.cumsum
方法。
作为一般规则,当计算可以并行地应用于数组(或数组集)的所有元素时,ufunc
代码是最快且最简单的 - 也就是说,不是取决于迭代的顺序。然后我们可以将动作委托给快速编译的numpy函数,如数组加法和乘法。如果计算本质上是串行的(j的值取决于j-1),这就变得更加棘手。
因此,如果我的粗略阅读是正确的,那么if语句就不是困难的,这是循环的串行性质。
=========================
在游戏中,我能够删除numpy
(实际上有3个子例子),但它仍然必须是迭代的:
if