如何对 2D numpy 数组进行平方或求幂(按元素)?

问题描述 投票:0回答:3

我需要对 2D numpy 数组(按元素)进行平方,我尝试了以下代码:

import numpy as np
a = np.arange(4).reshape(2, 2)
print a^2, '\n'
print a*a

产生:

[[2 3]
[0 1]]

[[0 1]
[4 9]]

显然,符号

a*a
给了我我想要的结果,而不是
a^2

我想知道是否存在另一种表示法来将 numpy 数组计算为 2 或 N 次方?而不是

a*a*a*..*a

python arrays numpy
3个回答
86
投票

最快的方法是执行

a*a
a**2
np.square(a)
,而
np.power(a, 2)
则要慢得多。

如果您传递另一个指数数组而不是

np.power()

,则 
2
允许您为每个元素使用不同的指数。从 @GarethRees 的评论中,我刚刚了解到该函数会给您带来与
a**2
a*a
不同的结果,这在公差较小的情况下变得很重要。

我使用 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

4
投票
>>> 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]])
>>>

精准

根据评论中 @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

性能

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

0
投票

np.square(A) 与 A**2 不同。后者计算矩阵乘法。

>>> np.square(np.mat([[1,2],[3,4]]))
matrix([[ 1,  4],
        [ 9, 16]])
>>> (np.mat([[1,2],[3,4]]))**2
matrix([[ 7, 10],
        [15, 22]])
© www.soinside.com 2019 - 2024. All rights reserved.