我有一个函数x,如下所示,它接受两个numpy数组作为输入,我想在一些计算后返回一个布尔值。
import numpy as np
def x(a,b):
print(a)
print(b)
# Some computation...
return boolean_value
wrappedFunc = np.frompyfunc(x,nin=2,nout=1)
arg_a = np.arange(8).reshape(2,4)
# arg_b is a numpy array having shape (2,1)
arg_b = np.array((np.array([[0, 1, 0],
[0, 0, 0],
[1, 0, 0],
[1, 1, 0]]),
np.array([[0., 1., 0.],
[0., 0., 0.],
[1., 0., 0.],
[1., 1., 0.],
[0.5, 0.5, 0.]])), dtype=object).reshape(2, 1)
字符串
执行上面的代码会得到以下输出。
# Output of a is:
0
1
2
3
4
5
6
7
# output of b is:
[[0 1 0]
[0 0 0]
[1 0 0]
[1 1 0]]
[[0 1 0]
[0 0 0]
[1 0 0]
[1 1 0]]
[[0 1 0]
[0 0 0]
[1 0 0]
[1 1 0]]
[[0 1 0]
[0 0 0]
[1 0 0]
[1 1 0]]
[[0. 1. 0. ]
[0. 0. 0. ]
[1. 0. 0. ]
[1. 1. 0. ]
[0.5 0.5 0. ]]
[[0. 1. 0. ]
[0. 0. 0. ]
[1. 0. 0. ]
[1. 1. 0. ]
[0.5 0.5 0. ]]
[[0. 1. 0. ]
[0. 0. 0. ]
[1. 0. 0. ]
[1. 1. 0. ]
[0.5 0.5 0. ]]
[[0. 1. 0. ]
[0. 0. 0. ]
[1. 0. 0. ]
[1. 1. 0. ]
[0.5 0.5 0. ]]
型
正如你所看到的,变量a
和b
分别被打印了8次,这不是预期的行为,因为我期望分别看到a
和b
的print语句的输出两次。print(a)
和print(b)
语句的预期输出如下所示:
On first call:
a needs to be:[0,1,2,3]
b needs to be:[[0 1 0]
[0 0 0]
[1 0 0]
[1 1 0]]
On second call:
a needs to be:[4,5,6,7]
b needs to be:[[0. 1. 0. ]
[0. 0. 0. ]
[1. 0. 0. ]
[1. 1. 0. ]
[0.5 0.5 0. ]]
型
我做错什么了?
1条答案
按热度按时间ac1kyiln1#
让我们看看
frompyfunc
与一个更简单的b
,并将其与简单的numpy
加法进行比较。字符串
a(2,4)与a(2,1)相加得到a(2,4)。根据
broadcasting
的规则,大小为1的维度被“复制”以匹配a
的4:型
定义一个简单的函数来添加两个“标量”。就像写的那样,它可以处理数组,包括
a
和b
,但是想象一下,有一些if
行只能处理标量。型
使用
frompyfunc
创建一个ufunc
,它可以将broadcast
作为其参数,将标量值传递给x
:型
你似乎想要的是数组在第一维上的
zip
:型
请注意,
x
在这里得到一个(4,)和(1,)形状的数组,再次通过broadcasting
得到一个(4,)结果。这两个输出数组可以连接起来,得到与前面相同的(4,2):
型
一个相关的函数
vectorize
接受一个signature
,它允许我们在第一个轴上指定迭代。要正确地做到这一点需要一些练习(尽管我第一次尝试就做对了!):型
vectorize
有一个性能免责声明,这对signature
版本来说是双重的。frompyfunc
通常表现更好(当它做我们想要的事情时)。对于小数组,列表解析通常做得更好,但是对于大数组,
vectorize
似乎扩展得更好,并且最终具有适度的速度优势。但是为了获得最佳的numpy
性能,最好使用整个数组(真正的向量化),而没有任何“迭代”。