如何使用国旗与纽比?

2024-04-19 02:28:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我怎么用国旗和纽比?我把函数简化到了最低限度!在

import numpy as np
price = np.array([30, 30, 20, 25, 20])
S     = np.repeat(300, len(price))
flag  = np.array([1, 1, 0, 1, 1])
def Val(S,price,flag = 0):
    p = 4
    if   flag == 0: p = S + price
    elif flag == 1: p = S - price
    return p

Val(S,price,flag.all())
#array([270, 270, 280, 275, 280])

Val(S,price, flag.any())
#array([330, 330, 320, 325, 320])

我本以为会这样:

^{pr2}$

这是另一个带有标志的等式的函数示例。我该怎么办 对它应用一个新的解决方案?在

来自http://www.espenhaug.com/black_scholes.html

   def CND(X):
        (a1,a2,a3,a4,a5) = (0.31938153, -0.356563782, 1.781477937, -1.821255978, 1.330274429)
        L = abs(X)
        K = 1.0 / (1.0 + 0.2316419 * L)
        w = 1.0 - 1.0 / sqrt(2*pi)*exp(-L*L/2.) * (a1*K + a2*K*K + a3*pow(K,3) + a4*pow(K,4) + a5*pow(K,5))
        if X<0: w = 1.0-w
        return w
    # Black Scholes Function

    def BlackScholes(CallPutFlag,S,X,T,r,v):
        d1 = (log(S/X)+(r+v*v/2.)*T)/(v*sqrt(T))
        d2 = d1-v*sqrt(T)
        if CallPutFlag=='c': return S*CND(d1)-X*exp(-r*T)*CND(d2)
        else:                return X*exp(-r*T)*CND(-d2)-S*CND(-d1)

Tags: 函数returnifdefa1npvalsqrt
3条回答

我将在这里做一个假设,猜测您决定传递flag.any()和{}作为参数,因为传递flag本身会在if语句中引发以下问题:

ValueError: The truth value of an array with more than one element
is ambiguous. Use a.any() or a.all()

要解决此问题,请记住S和{}是相同大小的numpy数组。numpy非常擅长在相同大小的数组上逐个元素地进行数学运算。还请注意,您在if语句的两个分支中执行的操作完全相同:p = S * flag,这意味着您不需要if语句来决定要做什么:

^{pr2}$

在这里,您只需要调用Val(S, flag)并获得预期的数组。这意味着输出数组的每个元素都是S和{}对应元素的乘积。在

您当前的代码看起来像是在尝试实现一个对单个数组元素有效的操作,并期望它应用于整个数组。这并不是numpy通常的工作方式(尽管也有写类似内容的方法)。在

flag.all()的值都是真值(即非零)时,flag.all()返回一个真实值,而当flags包含任何个真实值时,flag.any()返回一个真实值。一旦某个元素被证明为零,则返回False。在

在这里,您可能需要zip将标志和S放在一起:

for s, flg in zip(S, flag):
    if flg: # do this
    else: # do that

总之,p的定义如下:

^{pr2}$

这显示了一种可以做到这一点的算法,尽管数学也有帮助:

p = flag * S

这里*表示Hadamard乘积(相同大小的矩阵的元素乘积),与np.dot-矩阵乘法运算相反。在

if CallPutFlag=='c':

CallPutFlag是一个具有字符/字符串值的Python变量。所以它被用作开关。如果“c”使用一个等式;如果不是“c”(可能是“p”),则使用另一个等式。在

Val中,flag有两种用法:

^{pr2}$

你测试它的价值,然后用它乘以它。在if flag==0上下文中,它必须是标量。在此上下文中使用数组会引发一个公共ValueError。在

In [469]: np.array([0,1,0,1])==0
Out[469]: array([ True, False,  True, False], dtype=bool)

In [470]: if np.array([0,1,0,1])==0:print('yes')
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Pythonif可以操作也可以不操作,它不能为布尔数组的每个值来回翻转。在

但是对于乘法S*flagflag可以是一个大小与S匹配的数组。在

In [471]: np.arange(4)*np.array([0,1,0,1])
Out[471]: array([0, 1, 0, 3])

所以问题是,在Val中,何时返回{},何时{}。正如所写的,目前还不清楚。在

=============

In [513]: price = np.array([30, 30, 20, 25, 20])
     ...: S     = np.repeat(300, len(price))
     ...: flag  = np.array([1, 1, 0, 1, 1])
     ...: 
In [514]: np.where(flag, S+price, S-price)
Out[514]: array([330, 330, 280, 325, 320])

此列表的理解等价物为:

[s1 if f else s2 for f,s1,s2 in zip(flag,S+price,S-price)]
[s+p if f else s-p for f,s,p in zip(flag,S,price)]

掩蔽法

In [528]: result=S-price
In [529]: result[flag]=S[flag]+price[flag]
In [530]: result
Out[530]: array([330, 330, 280, 275, 280])

另一种掩蔽方法

In [543]: p=price.copy()
In [544]: p[flag==0] *= -1
In [545]: p
Out[545]: array([ 30,  30, -20,  25,  20])
In [546]: S+p
Out[546]: array([330, 330, 280, 325, 320])

where可能更快,除非计算替代方案很昂贵。或者如果其中一个备选方案产生了错误的值(例如S/0)。但你必须定时才能确定。在

相关问题 更多 >