在 Python 中,我可以遍历单个值吗?
In Python can I loop over a single value?
我有一个包含 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 中的常量只需要将该常量放入列表中以使其可迭代。谢谢大家的回答。
关于使常量可迭代的下一步......
使用 isinstance 检查数据类型似乎比 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
我有一个包含 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 中的常量只需要将该常量放入列表中以使其可迭代。谢谢大家的回答。 关于使常量可迭代的下一步...... 使用 isinstance 检查数据类型似乎比 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