如何使用NumPy数组算术Python向量化有限差分方法?

时间:2019-05-18 23:04:24

标签: python python-3.x numpy

尝试使用Numpy算术矢量化numpy值数组(不包括边值)上的有限差分方法。应该取周围值的平均值(上,下,左,右)进行计算。

例如,应该能够采用numpy数组,例如:

u = np.array([[100., 100., 100., 100., 100.],
             [100.,  0.,    0.,   0.,  100.],
             [100.,  0.,    0.,   0., 100.],
             [100.,  0.,    0.,   0., 100.],
             [100., 100., 100., 100., 100.]])

并返回:

[[100. 100. 100. 100. 100.]
[100.  50.  25.  50. 100.]
[100.  25.   0.  25. 100.]
[100.  50.  25.  50. 100.]
[100. 100. 100. 100. 100.]]

已经使它可以与for循环一起使用,但是效率很低。数组大小和值可能会有所不同。

到目前为止,我一直在尝试使用子数组对解决方案进行矢量化处理,但还无法弄清楚它是否能够正常工作:

import numpy as np

#example array
x = np.array([[100.,   2.,   3.,   7., 100.],
              [100.,   5.,   3.,   7., 100.],
              [100.,   3.,   6.,   3., 100.],
              [50.,   4.,   5.,   2., 100.],
              [100., 100., 100., 100., 100.]])

lbarrier = (np.size(x, 1))+1
rbarrier = (np.size(x, 1))-1
bbarrier = (np.size(x, 0))-1




#inner vals
itops = x[0:bbarrier][1:rbarrier][0][1:rbarrier]
ibot = x[0:bbarrier][1:rbarrier][-1][1:rbarrier]
ileft = x[1:bbarrier,1]
iright = x[1:bbarrier,-2]



#edge vals
etops = np.array(x[0:][0:][0][1:-1])
ebot = np.array(x[0:][0:][-1][1:-1])
eleft = np.array(x[1:bbarrier, 0])
eright = np.array(x[1:bbarrier, -1])

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

这种类型的操作在图像处理中很常见。您正在将矩阵与“内核”“卷积”。 scipy具有ndimage可以做到这一点。看起来您已经用100的边填充了内部矩阵。所以这适用于内部:

In [49]: from scipy import ndimage                                              

In [50]: import numpy as np                                                     

In [51]: k                                                                      
Out[51]: 
array([[0.  , 0.25, 0.  ],
       [0.25, 0.  , 0.25],
       [0.  , 0.25, 0.  ]])

In [52]: u = np.zeros((3,3))                                                    

In [53]: ndimage.convolve(u, k, mode='constant', cval=100.0)                    
Out[53]: 
array([[50., 25., 50.],
       [25.,  0., 25.],
       [50., 25., 50.]])

In [54]:      

您可能需要修改上面的内容才能获得想要的东西,但是我认为这是您想要的道路。

答案 1 :(得分:-1)

您可以使用scipy.signal.convolve

from scipy.signal import convolve

mask = [[0, 1, 0], 
        [1, 0, 1], 
        [0, 1, 0]]

convolved = convolve(u, mask, mode='valid') / np.sum(mask)

mask表示与结果中的元素相关的哪些源元素被组合以给出该元素。因此,这为您提供了一个(3, 3)数组,其中包含预期输出的中心(mode='valid'被传递以忽略边)。

然后我们可以将其放回原件的副本中:

result = u.copy()
result[1:-1, 1:-1] = convolved

print(result)

输出:

[[100. 100. 100. 100. 100.]
 [100.  50.  25.  50. 100.]
 [100.  25.   0.  25. 100.]
 [100.  50.  25.  50. 100.]
 [100. 100. 100. 100. 100.]]