我该如何计算" pn"自动?

时间:2017-08-10 19:11:15

标签: python numpy

我需要一些帮助来创建一个脚本来计算" pn"自动。

现在我有了这段代码:

import numpy as np
from itertools import product


a=np.arange(1,4,1) 
po= [] 
po = list(product(a, repeat =2))
array1= np.array(po)
array2= np.array([[2,40],[3,40],[4,43]])
p1=array1[0,0]*array2[:,1:]**array1[0,1] 
p2=array1[1,0]*array2[:,1:]**array1[1,1] 
p3=array1[2,0]*array2[:,1:]**array1[2,1] 

array1表示有序对,array2表示深度值。

等式为pn = array1(first element of pn line)*array2(the second column)**array1(second element of pn line)

我该如何解决?如何自动计算所有p? 非常感谢。

2 个答案:

答案 0 :(得分:1)

您可以一次性计算pi的所有i = 1,...,n

ps = (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T[..., None]

其中

p1  equals ps[0], 
p2  equals ps[1], 
...

pn equals ps[n-1]

例如,

import numpy as np
from itertools import product

a = np.arange(1, 4, 1)
po = []
po = list(product(a, repeat=2))
array1 = np.array(po)
array2 = np.array([[2, 40], [3, 40], [4, 43]])
p1 = array1[0, 0] * array2[:, 1:]**array1[0, 1]
p2 = array1[1, 0] * array2[:, 1:]**array1[1, 1]
p3 = array1[2, 0] * array2[:, 1:]**array1[2, 1]

ps = (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T[..., None]

assert np.allclose(p1, ps[0])
assert np.allclose(p2, ps[1])
assert np.allclose(p3, ps[2])

通过考虑组件阵列的形状找到了这个表达式。

In [294]: array2[:, 1:].shape
Out[294]: (3, 1)

In [295]: array1[:, 1].shape
Out[295]: (9,)

Broadcasting允许我们计算(array2[:, 1:]**array1[:, 1]),创建一个形状数组(3,9):

In [296]: (array2[:, 1:]**array1[:, 1]).shape
Out[296]: (3, 9)

由于array1[:, 0]是一维形状的数组(9,):

In [297]: array1[:, 0].shape
Out[297]: (9,)

我们可以再次使用广播将两者相乘,形成一个形状数组(3,9):

In [299]: (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).shape
Out[299]: (3, 9)

由于我们希望p1成为ps[0]p2成为ps[1],依此类推, 我们希望长度9的维度成为第一个轴。转换:

In [300]: (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T.shape
Out[300]: (9, 3)

由于p1的形状为(3, 1),而不仅仅是(3,),因此我们需要为结果添加另一个维度。这是按[..., None]编制索引的目的。

In [304]: (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T[..., None].shape
Out[304]: (9, 3, 1)

答案 1 :(得分:0)

创建变量n,并在数组索引需要更改的位置使用它。为方便起见,我把它放在一个函数调用中,不得不从n中减去1,因为数组从0开始。

def calculate_pn(n):
    pn = array1[n-1,0]*array2[:,n-1:]**array1[n-1,1]
    return pn

> calculate_pn(n=1)
array([[40],
       [40],
       [43]], dtype=int32)

您可以使用一系列值调用此值来计算多个p值。下面我使用dict理解来生成一个p值在1和array1中元素数之间的查找表。

> p = { n:calculate_pn(n) for n in range(1, len(array1)) }
> p[1]
array([[ 2, 40],
       [ 3, 40],
       [ 4, 43]], dtype=int32)

(您可能希望编辑calculate_pn以接受array1和array2作为参数)