矢量化numpy操作

时间:2017-09-26 12:03:36

标签: python arrays numpy

我有一个numpy ndarray V.我的操作是H =(V / a)** b,其中a和b只是标量。这很简单,但我需要进行多次实验(数千次),我会尝试不同的变体和b。使用for循环很容易做到这一点,但我想让它尽可能快地运行,所以我想要矢量化。所以,假设我已经生成了a和b的1D ndarray。给定3个1D阵列V,a和b,我该如何有效地做到这一点?谢谢!

2 个答案:

答案 0 :(得分:1)

您可以这样做:

import numpy as np

V = np.arange(100.0)
a = np.random.rand(50)
b = np.random.rand(50)

result = (V[np.newaxis, :] / a[:, np.newaxis]) ** b[:, np.newaxis]

result的大小为50x100,因此result[i]将是使用参数a[i]b[i]的结果。

答案 1 :(得分:0)

这就是广播的来源,您可以添加尺寸,以便数组沿每个轴广播:

(V/a[:, None])**b[:, None, None]

这会将一个尾随维度添加到a,将两个尾随维度添加到b,广播将确保您获得3D数组。这是有效的,因为广播总是沿着最后一个轴“广播”。

例如:

>>> import numpy as np
>>> V = np.array([1,2,3])
>>> a = np.array([0.1, 0.2, 0.3])
>>> b = np.array([1, 0.5, 0.34])

>>> a[:, None]
array([[ 0.1],
       [ 0.2],
       [ 0.3]])

>>> b[:, None, None]
array([[[ 1.  ]],

       [[ 0.5 ]],

       [[ 0.34]]])

>>> (V/a[:, None])**b[:, None, None]
array([[[ 10.        ,  20.        ,  30.        ],
        [  5.        ,  10.        ,  15.        ],
        [  3.33333333,   6.66666667,  10.        ]],

       [[  3.16227766,   4.47213595,   5.47722558],
        [  2.23606798,   3.16227766,   3.87298335],
        [  1.82574186,   2.5819889 ,   3.16227766]],

       [[  2.18776162,   2.7691737 ,   3.17849276],
        [  1.72842206,   2.18776162,   2.51114059],
        [  1.50583981,   1.90602666,   2.18776162]]])

请注意,这可能需要大量内存。因此,如果所有数组都很长,则可能无法使用它。

例如,如果所有数组都包含1000个值,那么结果将包含10亿个元素,这需要大量的RAM(约{7.5} float64 s。)