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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:46:22  来源:igfitidea点击:

How to square or raise to a power (elementwise) a 2D numpy array?

pythonarraysnumpy

提问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]