python-如何应用将向量返回到每个numpy数组元素的函数(并获取具有更高维的数组)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python-如何应用将向量返回到每个numpy数组元素的函数(并获取具有更高维的数组),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4107字,纯文字阅读大概需要6分钟。
内容图文
![python-如何应用将向量返回到每个numpy数组元素的函数(并获取具有更高维的数组)](/upload/InfoBanner/zyjiaocheng/690/177a4fbeae504eebbd4b341e32b29494.jpg)
让我们直接用代码编写
注意:我编辑了映射器(例如,原始示例使用x->(x,2 * x,3 * x))到通用黑盒函数,这会造成麻烦.
import numpy as np
def blackbox_fn(x): #I can't be changed!
assert np.array(x).shape == (), "I'm a fussy little function!"
return np.array([x, 2*x, 3*x])
# let's have 2d array
arr2d = np.array(list(range(4)), dtype=np.uint8).reshape(2, 2)
# each element should be mapped to vector
def mapper(x, blackbox_fn):
# there is some 3rdparty non-trivial function, returning np.array
# in examples returns np.array((x, 2 * x, 3 * x))
# but still this 3rdparty function operates only on scalar values
return vectorized_blackbox_fn(x)
所以对于输入二维数组
array([[0, 1],
[2, 3]], dtype=uint8)
我想获得3D阵列
array([[[0, 0, 0],
[1, 2, 3]],
[[2, 4, 6],
[3, 6, 9]]], dtype=uint8)
我可以使用for循环编写朴素算法
# result should be 3d array, last dimension is same as mapper result size
arr3d = np.empty(arr2d.shape + (3,), dtype=np.uint8)
for y in range(arr2d.shape[1]):
for x in xrange(arr2d.shape[0]):
arr3d[x, y] = mapper(arr2d[x, y])
但是对于大型阵列而言似乎相当慢.
我知道有np.vectorize,但是使用
np.vectorize(mapper)(arr2d)
不起作用,因为
ValueError: setting an array element with a sequence.
(似乎矢量化不能更改尺寸)
有更好的解决方案(numpy惯用且更快)吗?
解决方法:
使用带有新签名选项的np.vectorize可以解决此问题.它不会提高速度,但会使维簿记更容易.
In [159]: def blackbox_fn(x): #I can't be changed!
...: assert np.array(x).shape == (), "I'm a fussy little function!"
...: return np.array([x, 2*x, 3*x])
...:
签名文档有点含糊.我以前使用过它,所以做了一个很好的第一个猜测:
In [161]: f = np.vectorize(blackbox_fn, signature='()->(n)')
In [162]: f(np.ones((2,2)))
Out[162]:
array([[[ 1., 2., 3.],
[ 1., 2., 3.]],
[[ 1., 2., 3.],
[ 1., 2., 3.]]])
与您的数组:
In [163]: arr2d = np.array(list(range(4)), dtype=np.uint8).reshape(2, 2)
In [164]: f(arr2d)
Out[164]:
array([[[0, 0, 0],
[1, 2, 3]],
[[2, 4, 6],
[3, 6, 9]]])
In [165]: _.dtype
Out[165]: dtype('int32')
不会保留dtype,因为您的blackbox_fn不会保留它.默认情况下,vectorize使用第一个元素进行测试计算,并使用其dtype确定结果的dtype.可以使用otypes参数指定return dtype.
它可以处理2d以外的数组:
In [166]: f(np.arange(3))
Out[166]:
array([[0, 0, 0],
[1, 2, 3],
[2, 4, 6]])
In [167]: f(3)
Out[167]: array([3, 6, 9])
具有签名的矢量化使用Python级别的迭代.如果没有签名,它将使用np.frompyfunc,性能会更好一些.但是,只要必须为输入的元素调用blackbox_fn,我们就无法将速度提高很多(最多2倍).
np.frompyfunc返回一个对象dtype数组:
In [168]: fpy = np.frompyfunc(blackbox_fn, 1,1)
In [169]: fpy(1)
Out[169]: array([1, 2, 3])
In [170]: fpy(np.arange(3))
Out[170]: array([array([0, 0, 0]), array([1, 2, 3]), array([2, 4, 6])], dtype=object)
In [171]: np.stack(_)
Out[171]:
array([[0, 0, 0],
[1, 2, 3],
[2, 4, 6]])
In [172]: fpy(arr2d)
Out[172]:
array([[array([0, 0, 0]), array([1, 2, 3])],
[array([2, 4, 6]), array([3, 6, 9])]], dtype=object)
在这种2d情况下,stack无法删除数组嵌套:
In [173]: np.stack(_)
Out[173]:
array([[array([0, 0, 0]), array([1, 2, 3])],
[array([2, 4, 6]), array([3, 6, 9])]], dtype=object)
但我们可以将其拆散并堆叠.它需要重塑:
In [174]: np.stack(__.ravel())
Out[174]:
array([[0, 0, 0],
[1, 2, 3],
[2, 4, 6],
[3, 6, 9]])
速度测试:
In [175]: timeit f(np.arange(1000))
14.7 ms ± 322 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [176]: timeit fpy(np.arange(1000))
4.57 ms ± 161 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [177]: timeit np.stack(fpy(np.arange(1000).ravel()))
6.71 ms ± 207 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [178]: timeit np.array([blackbox_fn(i) for i in np.arange(1000)])
6.44 ms ± 235 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
让函数返回列表而不是任何数组可能会使重组结果更容易,甚至可能更快
def foo(x):
return [x, 2*x, 3*x]
或使用frompyfunc参数;
def foo(x):
return x, 2*x, 3*x # return a tuple
In [204]: np.stack(np.frompyfunc(foo, 1,3)(arr2d),2)
Out[204]:
array([[[0, 0, 0],
[1, 2, 3]],
[[2, 4, 6],
[3, 6, 9]]], dtype=object)
10倍加速-我很惊讶:
In [212]: foo1 = np.frompyfunc(foo, 1,3)
In [213]: timeit np.stack(foo1(np.arange(1000)),1)
428 μs ± 17.9 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
内容总结
以上是互联网集市为您收集整理的python-如何应用将向量返回到每个numpy数组元素的函数(并获取具有更高维的数组)全部内容,希望文章能够帮你解决python-如何应用将向量返回到每个numpy数组元素的函数(并获取具有更高维的数组)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。