Python “计算”;“向内衍生工具”;二维网格的网格划分

Python “计算”;“向内衍生工具”;二维网格的网格划分,python,numpy,Python,Numpy,我将在2d中揭示这个问题,但最终需要在3D中解决它 假设我有以下网格 import numpy as np ge = np.arange(36).reshape((6, 6)) gu = ge + 10 f = ge - 2*gu**2 现在f看起来像这样: array([[ -200, -241, -286, -335, -388, -445], [ -506, -571, -640, -713, -790, -871], [ -956, -1

我将在2d中揭示这个问题,但最终需要在3D中解决它

假设我有以下网格

import numpy as np
ge = np.arange(36).reshape((6, 6))
gu = ge + 10
f = ge - 2*gu**2
现在
f
看起来像这样:

array([[ -200,  -241,  -286,  -335,  -388,  -445],
       [ -506,  -571,  -640,  -713,  -790,  -871],
       [ -956, -1045, -1138, -1235, -1336, -1441],
       [-1550, -1663, -1780, -1901, -2026, -2155],
       [-2288, -2425, -2566, -2711, -2860, -3013],
       [-3170, -3331, -3496, -3665, -3838, -4015]])
我可以获得外部网格点,如下所示:

现在,对于所有这些边界点,我想计算“内向导数”。现在,我们可以假设
e
u
上所有网格点之间的空间为一。然后,
f[0,1]
的网格向内导数可以计算为

(-571-(-241))/(1) = -330
对于角点
[0,0]
,向内导数是w.r.t.对角线元素
[1,1]
,我们可以在这里计算为

(-571 - (-200)/1 =  371
对于
[4,5]
,我们有
(-2860-(-3838))/1=987


我面临的主要问题是计算不同方向的导数,总是向内。否则,这只是
np.diff()
的情况。有什么有效的方法可以做到这一点,并且至少可以保持3维空间?

使用蒂尔·霍夫曼(Till Hoffmann)的精彩评论,我至少可以做到这一点

gradient
get在处理二进制矩阵时,符号是错误的,但是在处理整数时,我们会得到

mask = edge_mask(f)
a, b = np.gradient(mask.astype(int))
这给了我们一个(逆)符号(导数需要向内还是向外计算):

那么,我们就可以做了

-a * mask * np.gradient(f)[0]
Out[88]: 
array([[   0., -330., -354., -378., -402.,    0.],
       [   0.,   -0.,   -0.,   -0.,   -0.,    0.],
       [   0.,    0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,    0.,    0.,    0.],
       [   0.,  906.,  930.,  954.,  978.,    0.]])
-b * mask * np.gradient(f)[1]
Out[89]: 
array([[   0.,    0.,    0.,    0.,    0.,    0.],
       [ -65.,   -0.,    0.,    0.,    0.,   81.],
       [ -89.,   -0.,    0.,    0.,    0.,  105.],
       [-113.,   -0.,    0.,    0.,    0.,  129.],
       [-137.,   -0.,    0.,    0.,    0.,  153.],
       [   0.,    0.,    0.,    0.,    0.,    0.]])

现在缺少的是角点——我有点困在这里了。

np.gradient
是类固醇上的
np.diff
,可能很合适。嗯,角点很棘手——特别是如果你不想只计算一阶线性近似值的话。我不知道这是否适用于您,但您可以尝试以下方法:使用
d=f[np.diag\u index\u from(f)]
获得矩阵的对角线,然后计算
d
上的导数。这将为您提供左上角和右下角。然后对其他两个角使用反对角线?@TillHoffmann问题将是对
n
尺寸进行反对角线,或者至少是三维尺寸,以简洁易读的方式。
a
Out[90]: 
array([[ 0. , -1. , -1. , -1. , -1. ,  0. ],
       [ 0. , -0.5, -0.5, -0.5, -0.5,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0.5,  0.5,  0.5,  0.5,  0. ],
       [ 0. ,  1. ,  1. ,  1. ,  1. ,  0. ]])
b
Out[91]: 
array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
       [-1. , -0.5,  0. ,  0. ,  0.5,  1. ],
       [-1. , -0.5,  0. ,  0. ,  0.5,  1. ],
       [-1. , -0.5,  0. ,  0. ,  0.5,  1. ],
       [-1. , -0.5,  0. ,  0. ,  0.5,  1. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ]])
-a * mask * np.gradient(f)[0]
Out[88]: 
array([[   0., -330., -354., -378., -402.,    0.],
       [   0.,   -0.,   -0.,   -0.,   -0.,    0.],
       [   0.,    0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,    0.,    0.,    0.],
       [   0.,  906.,  930.,  954.,  978.,    0.]])
-b * mask * np.gradient(f)[1]
Out[89]: 
array([[   0.,    0.,    0.,    0.,    0.,    0.],
       [ -65.,   -0.,    0.,    0.,    0.,   81.],
       [ -89.,   -0.,    0.,    0.,    0.,  105.],
       [-113.,   -0.,    0.,    0.,    0.,  129.],
       [-137.,   -0.,    0.,    0.,    0.,  153.],
       [   0.,    0.,    0.,    0.,    0.,    0.]])