在Python中建立三维阵列,以取代优化循环(Building 3D arrays in Pytho

2019-10-30 11:45发布

我试图更好地理解Python的优化,所以这是一个虚拟的情况,但希望勾勒我的想法......

说我有一个函数,它接受两个变量:

def func(param1, param2):
    return some_func(param1) + some_const*(param2/2)

和我有参数1和参数(长度不同的)阵列,在该欲被评估的功能,(some_func是参数1的任意功能),例如

param1 = np.array((1,2,3,4,5))
param2 = np.array((5,2,3,1,9, 9, 10))

我可以评估在做所有的参数空间:

result = []
for p in param1:
    result.append(func(p, param2))
result = np.asarray(result)

然而,在Python环比数组运算慢。 因此,我不知道有没有办法实现了三维数组,它包含FUNC的结果在这两个参数1和参数数组的所有值?

Answer 1:

你举的例子:

In [198]: result=[]
In [199]: for p in param1:
   .....:     result.append(p+3*(param2/2))
In [200]: result=np.array(result)

同样的结果通过广播(和np.newaxis ):

In [197]: param1[:,None] + 3*(param2[None,:]/2)
Out[197]: 
array([[ 7,  4,  4,  1, 13, 13, 16],
       [ 8,  5,  5,  2, 14, 14, 17],
       [ 9,  6,  6,  3, 15, 15, 18],
       [10,  7,  7,  4, 16, 16, 19],
       [11,  8,  8,  5, 17, 17, 20]])

详情some_func将决定是否使用some_func(param1[:,None])some_func(param1)[:,None]



Answer 2:

对于some_func(参数1)原来的答复X参数2

some_func以这样一种方式,它可以接受并返回numpy的阵列。 然后使用;

numpy.outer(some_func(param1), param2)

这工作,因为在你的榜样,无论是param1param2向量 (一维数组),这样你就可以使用outer ,其结果将是一个二维数组,而不是3D。

编辑

只要你想要做的操作是通用的功能 (“ufunc”),你可以使用它的outer方法;

In [1]: import numpy as np

In [2]: a = np.arange(10)

In [3]: a
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [4]: b = np.arange(15)

In [5]: np.add.outer(a, b)
Out[5]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
       [ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16],
       [ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17],
       [ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18],
       [ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
       [ 7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
       [ 8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22],
       [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])


Answer 3:

您可以使用numpy的广播,如hpaulj建议。 这通常是攻击矢量化numpy的操作的第一道防线。 采用广播的本质,是在这样做,你从慢蟒蛇水平移动你的循环到C级。

另外,您也可以选择看看numba和numexpr ,可完成矢量以更灵活的方式



文章来源: Building 3D arrays in Python to replace loops for optimization