在Python中,我可以在单个值上循环吗



我有一个由5个变量组成的函数。我想通过绘制一个曲面来可视化函数的行为,在这个曲面上,我跨越了2个变量的范围,并保持剩余的3个常数。

在我的例子中,函数是Black-Scholes,它是S,T,K,r,S的函数:BS(S、T、K、r、S(

我想画出BS(S、T、Kvec、r、svec(其中K和s用矢量输入替换。或BS(Svec、Tvec、K、r、s(其中,S和T用矢量输入替换。或BS(S、Tvec、K、r、svec(其中,T和K被向量输入所代替。

总之,我想让用户输入2个向量和3个常量,然后让函数自适应。

我怎么能优雅地做到这一点而不编码所有5个选择2个案例?

我曾尝试将所有输入转换为Numpy数组,然后进行迭代,但具有单个值的Numpy数组是不可迭代的。

def BS_Call_HyperCube(Svec,Kvec,Tvec,rvec,svec):
Svec = np.asarray(Svec)
Kvec = np.asarray(Kvec)
Tvec = np.asarray(Tvec)
rvec = np.asarray(rvec)
svec = np.asarray(svec)
for S in Svec:
for K in Kvec:
for T in Tvec:
print(S,K,T)

我也试过这个:

def BS_Call_HyperCube(Svec,Kvec,Tvec,rvec,vvec):
nS = 1 if isinstance(Svec,(int,float)) else len(Svec)
nK = 1 if isinstance(Kvec,(int,float)) else len(Kvec)
nT = 1 if isinstance(Tvec,(int,float)) else len(Tvec)
nr = 1 if isinstance(rvec,(int,float)) else len(rvec)
nv = 1 if isinstance(svec,(int,float)) else len(vvec)
cube = np.ndarray((nS,nK,nT,nr,ns))

for iS in range(nS):
S = Svec[iS]
for iK in range(nK):
K = Svec[iK]
for iT in range(nT):
T = Svec[iT]
for ir in range(nr):
r = Svec[ir]
for iv in range(nv):
v = Svec[iv]

cube[iS,iK,iT,ir,iv] = BS_Call(S,K,T,r,v)


在python中,难道没有办法让一个退化循环只在一个常量上循环吗?

这真的不是实现这种black-scholes东西的好方法,但在不改变太多原始结构的情况下,开始吧:

def BS_Call_HyperCube(Svec,Kvec,Tvec,rvec,vvec):
try:
nS = len(Svec)
except TypeError:
nS = 1
Svec = [Svec]
try:
nS = len(Kvec)
except TypeError:
nS = 1
Kvec = [Kvec]
try:
nS = len(Tvec)
except TypeError:
nS = 1
Tvec = [Tvec]
try:
nS = len(rvec)
except TypeError:
nS = 1
rvec = [rvec]
try:
nS = len(vvec)
except TypeError:
nS = 1
vvec = [vvec]
cube = np.ndarray((nS,nK,nT,nr,ns))
for iS in range(nS):
S = Svec[iS]
for iK in range(nK):
K = Svec[iK]
for iT in range(nT):
T = Svec[iT]
for ir in range(nr):
r = Svec[ir]
for iv in range(nv):
v = Svec[iv]

cube[iS,iK,iT,ir,iv] = BS_Call(S,K,T,r,v)

显然,在python中循环一个常量只需将该常量放入列表中即可使其可迭代。谢谢大家的回答。关于使常量可迭代的下一步。。。使用isistance检查数据类型似乎比try-catch更优雅。如果这不正确,请告诉我。下面是我的解决方案。再次感谢大家。

S = 100; K = 100; T = 1; r = .05; s = .32
K = np.linspace(20,70,11)
T = np.linspace(.10,.60,11)
if isinstance(S,(int,float)):
nS = 1
Svec = [S]
else:
nS = len(S)
Svec = S
if isinstance(T,(int,float)):
nT = 1
Tvec = [T]
else:
nT = len(T)
Tvec = T
if isinstance(K,(int,float)):
nK = 1
Kvec = [K]
else:
nK = len(K)
Kvec = K
if isinstance(r,(int,float)):
nr = 1
rvec = [r]
else:
nr = len(r)
rvec = r
if isinstance(s,(int,float)):
ns = 1
svec = [s]
else:
ns = len(s)
svec = s

cube = np.ndarray((nS,nK,nT,nr,ns))
for iS in range(nS):
xS = Svec[iS]
for iK in range(nK):
xK = Kvec[iK]
for iT in range(nT):
xT = Tvec[iT]
for ir in range(nr):
xr = rvec[ir]
for iv in range(ns):
xs = svec[iv]

cube[iS,iK,iT,ir,iv] = BS_Call(xS,xK,xT,xr,xs)

square = np.squeeze(cube)
square.shape

最新更新