如何使用 2x2 数组对 Python 中的巨大二维数组进行采样以创建字典? (Python 的模板算法)

How to sample a huge 2D array in Python using 2x2 arrays to create a dictionary? (Stencil Algorithm for Python)

我是编程新手,所以如果这是一个经典而琐碎的问题,我深表歉意。我有一个 100x100 值的二维数组,它是通过 matplotlib 绘制的。在此图像中,每个单元格都有其值(范围从 0.01.0)和 ID(从左上角开始,范围从 09999)。我想通过使用产生两个 dictionaries:

的 2x2 移动 window 对矩阵进行采样

在下面的示例中(左上面板),其中 N 的 ID=0,第一个字典将产生 {'0': (0,1,100,101)} 因为单元格向右编号为 0 到 99,向下编号为 0 到 9900,步长 = 100。第二个字典将产生 {'0': 0.775},因为 0.775 是 N 的 4 个相邻单元格的平均值。当然,这些字典必须具有与我在二维数组上的 "intersections" 一样多的键。

如何做到这一点?在这种情况下,字典是最好的 "tool" 吗?谢谢大家!

PS: 我尝试了自己的方法,但我的代码不完整,错误,我无法理解它:

a=... #The 2D array which contains the cell values ranging 0.0 to 1.0
neigh=numpy.zeros(4)
mean_neigh=numpy.zeros(10000/4)
for k in range(len(neigh)):
    for i in a.shape[0]:
        for j in a.shape[1]:
            neigh[k]=a[i][j]
            ...

好吧,字典实际上可能就是您的情况。

您确定您使用的 numpy.array 格式正确吗?我在 API 中找不到任何 array((int, int)) 形式。无论如何...

声明二维数组后要做什么

为了让事情井井有条,让我们创建两个可用于任何方形二维数组的函数,返回您需要的两个字典:

#this is the one that returns the first dictionary
def dictionarize1(array):
    dict1 = {}
    count = 0
    for x in range(len(array[0]) - 1) :
        for y in range(len(array[0]) - 1):
            dict1[count] = [array[x][y], array[x][y+1], array[x+1][y], array[x + 1][y+1]]
            count = count + 1
    return dict1

def dictionarize2(array):
    dict2 = {}
    counter = 0
    for a in range(len(array[0]) - 1) :
        for b in range(len(array[0]) - 1):
            dict2[counter] = (array[a][b] + array[a][b+1] + array[a+1][b] + array[a + 1][b+1])/4
            counter = counter + 1
    return dict2

#here's a little trial code to see them working

eighties = [[2.0, 2.2, 2.6, 5.7, 4.7], [2.1, 2.3, 2.3, 5.8, 1.6], [2.0, 2.2, 2.6, 5.7, 4.7],[2.0, 2.2, 2.6, 5.7, 4.7],[2.0, 2.2, 2.6, 5.7, 4.7]]
print("Dictionarize1: \n")
print(dictionarize1(eighties))
print("\n\n")
print("Dictionarize2: \n")
print(dictionarize2(eighties))
print("\n\n")

与第一个代码相比,我更喜欢使用整数作为关键原因 python 将打印在这种情况下排序的字典(字典根据定义是未排序的,但如果它们具有 int 键 Python 将打印出来按键排序)。但是,您可以像我之前那样使用 str(count) 将其改回字符串。

我希望这会有所帮助,现在我对数学库不是很实用,但我编写的代码应该适用于您可能想要作为输入的任何二维方形数组!

假设 data 是原始 numpy.array,行和列的维度为 drdc

dr = data.shape[0]
dc = data.shape[1]

您可以生成 Keys 作为 return 感兴趣索引的函数,并生成 Values 作为具有 4 个相邻单元格计算平均值的列表。 在这种情况下,Keys 等于:

def Keys(x):
    xmod = x + (x+1)/dc  # dc is in scope
    return [xmod, xmod + 1, xmod + dc, xmod + 1 + dc]

Values 的维度等于 dr-1 * dc-1,因为不包括最后一行和最后一列。我们可以将其计算为移动平均线并稍后重塑为 1D,(灵感来自 link):

Values = ((d[:-1,:-1] + d[1:,:-1] + d[:-1,1:] + d[1:,1:])/4).reshape((dr-1)*(dc-1))

示例:

dr = 3
dc = 5

In: np.array(range(dc*dr)).reshape((dr, dc))  # data
Out: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

In: [Keys(x) for x in range((dr-1)*(dc-1))]
Out: 
    [[0, 1, 5, 6],
     [1, 2, 6, 7],
     [2, 3, 7, 8],
     [3, 4, 8, 9],
     [5, 6, 10, 11],
     [6, 7, 11, 12],
     [7, 8, 12, 13],
     [8, 9, 13, 14]]

In: Values
Out: array([ 3,  4,  5,  6,  8,  9, 10, 11])