如何使用numpy旗帜?我将功能简化为最低限度!
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])
我在期待这个:
Val(S,price,flag.XX)
#array([330, 330, 280, 325, 320])
这是带标志的等式的另一个函数示例。我怎么样? 应用一个numpy解决方案?
来自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)
答案 0 :(得分:1)
在
中if CallPutFlag=='c':
CallPutFlag
是一个带有字符/字符串值的Python变量。所以它被用作开关。如果'c`使用一个等式;如果不是'c'(可能'p')使用另一个。
在Val
中,flag
以两种方式使用:
def Val(S, flag = 0):
p = 4
if flag == 0: p = S * flag
elif flag == 1: p = S * flag
return p
你测试它的值,然后乘以它。在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()
Python if
可以起作用与否,它不能为布尔数组的每个值来回翻转。
但对于乘法S*flag
,flag
可以是匹配S
大小的数组。
In [471]: np.arange(4)*np.array([0,1,0,1])
Out[471]: array([0, 1, 0, 3])
所以问题是,Val
何时要返回4
,何时S*flag
。如上所述,目前尚不清楚。
===============
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)。但是你必须确定时间。
答案 1 :(得分:0)
flag.all()
的值为真(即非零)时, flag
会返回真值,而当flag.any()
flags
时,False
会这样做包含任何个真值。一旦某个元素被证明为零,则返回zip
。
在这里,你可能想要S
旗帜和for s, flg in zip(S, flag):
if flg: # do this
else: # do that
在一起:
p
总而言之,p = np.array([s * flg for s, flg in zip(S, flg)])
将被定义为:
p = flag * S
这显示了一个可以做到这一点的算法,尽管数学也很有帮助:
*
此处np.dot
代表 Hadamard产品(相同大小的矩阵的元素乘积),而不是function filterChanged() {
window.history.pushState("", document.title, '?' + $("#FiltersForm").serialize())
}
- 矩阵乘法操作
答案 2 :(得分:0)
我想在这里走出困境,猜猜你决定将flag.any()
和flag.all()
作为参数传递,因为传递flag
本身会在{{1}中提出以下内容声明:
if
要解决此问题,请记住ValueError: The truth value of an array with more than one element
is ambiguous. Use a.any() or a.all()
和S
是相同大小的numpy数组。 numpy非常擅长在相同大小的数组上逐个元素地进行数学运算。另请注意,您在flag
语句的两个分支中执行完全相同的操作:if
,这意味着您不需要p = S * flag
语句来决定要执行的操作:
if
您只需要调用def Val(S, flag):
return S * flag
并获取预期的数组即可。这表示输出数组的每个元素都是Val(S, flag)
和S
的相应元素的乘积。
您当前的代码看起来正在尝试实现一个对单个数组元素起作用的操作,并希望将其应用于整个数组。这不是一般的numpy如何工作(虽然有办法写这样的东西)。