Numpy数组与向量参数的广播用法
在numpy中,能不能用向量作为参数来进行数组广播?
举个例子,我知道我可以这样做:
def bernoulli_fraction_to_logodds(fraction):
if fraction == 1.0:
return inf
return log(fraction / (1 - fraction))
bernoulli_fraction_to_logodds = numpy.frompyfunc(bernoulli_fraction_to_logodds, 1, 1)
这样就能对整个数组进行操作。如果我有一个函数,它接收一个包含两个元素的向量,并返回一个同样包含两个元素的向量。我能不能把一个包含多个两个元素向量的数组传给它?比如:
def beta_ml_fraction(beta):
a = beta[0]
b = beta[1]
return a / (a + b)
beta_ml_fraction = numpy.frompyfunc(beta_ml_fraction, 1, 1)
可惜的是,这样做是不行的。有没有类似于from_py_func的函数可以用呢?当向量是两个元素的时候,我可以找到解决办法,但如果是n个元素的向量呢?
因此,输入(2,3)
应该返回0.4
,而输入[[2,3], [3,3]]
应该返回[0.4, 0.5]
。
2 个回答
4
我觉得 frompyfunc
可能做不到这个,不过我也可能错了。
关于 np.vectorize
,有位叫 A. M. Archibald 的人写道:
实际上,任何通过 Python 代码来“组合两个数”的操作都会很慢。Python 循环慢并不是因为它的循环结构慢,而是因为执行 Python 代码本身就慢。所以说,vectorize 有点像是个小把戏——它实际上并没有运行得更快,但用起来很方便。
所以 np.frompyfunc
(和 np.vectorize
)其实只是语法上的一种简化——它们并没有让 Python 函数运行得更快。在意识到这一点后,我对 frompyfunc
的兴趣几乎降到了零。
Python 的循环并没有什么难懂的地方,所以要么直接使用循环,要么重写函数,真正利用 numpy(通过编写真正的向量化公式)。
import numpy as np
def beta_ml_fraction(beta):
a = beta[:,0]
b = beta[:,1]
return a / (a + b)
arr=np.array([(2,3)],dtype=np.float)
print(beta_ml_fraction(arr))
# [ 0.4]
arr=np.array([(2,3),(3,3)],dtype=np.float)
print(beta_ml_fraction(arr))
# [ 0.4 0.5]
1
在处理二维向量数组时,我喜欢把x和y的部分放在第一个索引位置。为此,我经常使用transpose()这个函数。
def beta_ml_fraction(beta):
a = beta[0]
b = beta[1]
return a / (a + b)
arr=np.array([(2,3),(3,3)],dtype=np.float)
print(beta_ml_fraction(arr.transpose()))
# [ 0.4 0.5]
这种方法的好处是,处理多维的二维向量数组会变得更简单。
x = np.arange(18,dtype=np.float).reshape(2,3,3)
print(x)
#array([[[ 0., 1., 2.],
# [ 3., 4., 5.],
# [ 6., 7., 8.]],
#
# [[ 9., 10., 11.],
# [ 12., 13., 14.],
# [ 15., 16., 17.]]])
print(beta_ml_fraction(x))
#array([[ 0. , 0.09090909, 0.15384615],
# [ 0.2 , 0.23529412, 0.26315789],
# [ 0.28571429, 0.30434783, 0.32 ]])