Python 如何将二维 numpy 数组平方或提升到幂(元素)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25870923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to square or raise to a power (elementwise) a 2D numpy array?
提问by jmb_louis
I need to square a 2D numpy array (elementwise) and I have tried the following code:
我需要平方一个 2D numpy 数组(元素方式),我尝试了以下代码:
import numpy as np
a = np.arange(4).reshape(2, 2)
print a^2, '\n'
print a*a
that yields:
产生:
[[2 3]
[0 1]]
[[0 1]
[4 9]]
Clearly, the notation a*agives me the result I want and not a^2.
显然,符号a*a给了我我想要的结果而不是a^2。
I would like to know if another notation exists to raise a numpy array to the power of 2 or N? Instead of a*a*a*..*a.
我想知道是否存在另一种表示法来将 numpy 数组提高到 2 或 N 的幂?而不是a*a*a*..*a.
采纳答案by Saullo G. P. Castro
The fastest way is to do a*aor a**2or np.square(a)whereas np.power(a, 2)showed to be considerably slower.
最快的方法是 do a*aor a**2or np.square(a)whilenp.power(a, 2)显示相当慢。
np.power()allows you to use different exponents for each element if instead of 2you pass another array of exponents. From the comments of @GarethRees I just learned that this function will give you different results than a**2or a*a, which become important in cases where you have small tolerances.
np.power()如果不是2传递另一个指数数组,则允许您为每个元素使用不同的指数。从@GarethRees 的评论中,我刚刚了解到此函数会给您提供与a**2或不同的结果a*a,这在容差较小的情况下变得很重要。
I've timed some examples using NumPy 1.9.0 MKL 64 bit, and the results are shown below:
我已经使用 NumPy 1.9.0 MKL 64 位计时了一些示例,结果如下所示:
In [29]: a = np.random.random((1000, 1000))
In [30]: timeit a*a
100 loops, best of 3: 2.78 ms per loop
In [31]: timeit a**2
100 loops, best of 3: 2.77 ms per loop
In [32]: timeit np.power(a, 2)
10 loops, best of 3: 71.3 ms per loop
回答by user3666197
>>> import numpy
>>> print numpy.power.__doc__
power(x1, x2[, out])
First array elements raised to powers from second array, element-wise.
Raise each base in `x1` to the positionally-corresponding power in
`x2`. `x1` and `x2` must be broadcastable to the same shape.
Parameters
----------
x1 : array_like
The bases.
x2 : array_like
The exponents.
Returns
-------
y : ndarray
The bases in `x1` raised to the exponents in `x2`.
Examples
--------
Cube each element in a list.
>>> x1 = range(6)
>>> x1
[0, 1, 2, 3, 4, 5]
>>> np.power(x1, 3)
array([ 0, 1, 8, 27, 64, 125])
Raise the bases to different exponents.
>>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
>>> np.power(x1, x2)
array([ 0., 1., 8., 27., 16., 5.])
The effect of broadcasting.
>>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])
>>> x2
array([[1, 2, 3, 3, 2, 1],
[1, 2, 3, 3, 2, 1]])
>>> np.power(x1, x2)
array([[ 0, 1, 8, 27, 16, 5],
[ 0, 1, 8, 27, 16, 5]])
>>>
Precision
精确
As per the discussed observation on numerical precision as per @GarethRees objection in comments:
根据评论中@GarethRees 反对意见对数值精度的讨论观察:
>>> a = numpy.ones( (3,3), dtype = numpy.float96 ) # yields exact output
>>> a[0,0] = 0.46002700024131926
>>> a
array([[ 0.460027, 1.0, 1.0],
[ 1.0, 1.0, 1.0],
[ 1.0, 1.0, 1.0]], dtype=float96)
>>> b = numpy.power( a, 2 )
>>> b
array([[ 0.21162484, 1.0, 1.0],
[ 1.0, 1.0, 1.0],
[ 1.0, 1.0, 1.0]], dtype=float96)
>>> a.dtype
dtype('float96')
>>> a[0,0]
0.46002700024131926
>>> b[0,0]
0.21162484095102677
>>> print b[0,0]
0.211624840951
>>> print a[0,0]
0.460027000241
Performance
表现
>>> c = numpy.random.random( ( 1000, 1000 ) ).astype( numpy.float96 )
>>> import zmq
>>> aClk = zmq.Stopwatch()
>>> aClk.start(), c**2, aClk.stop()
(None, array([[ ...]], dtype=float96), 5663L) # 5 663 [usec]
>>> aClk.start(), c*c, aClk.stop()
(None, array([[ ...]], dtype=float96), 6395L) # 6 395 [usec]
>>> aClk.start(), c[:,:]*c[:,:], aClk.stop()
(None, array([[ ...]], dtype=float96), 6930L) # 6 930 [usec]
>>> aClk.start(), c[:,:]**2, aClk.stop()
(None, array([[ ...]], dtype=float96), 6285L) # 6 285 [usec]
>>> aClk.start(), numpy.power( c, 2 ), aClk.stop()
(None, array([[ ... ]], dtype=float96), 384515L) # 384 515 [usec]

