2015-10-19 99 views
1

我对编程颇为陌生,所以我很抱歉如果这是一个经典而平凡的问题。我有一个100x100 2D值数组,这是通过matplotlib绘制的。在此图像中,每个单元格的值(范围从0.01.0)和ID(从左上角开始的范围为09999)。我想通过使用2×2的移动,其产生两个字典窗口采样矩阵:如何在Python中使用2x2数组来创建一个巨大的二维数组来创建字典? (Python的模板算法)

  • 第一词典:键表示4个细胞的交点;该值表示具有4个相邻单元的ID的元组(参见下图 - ,该交点由“N”表示);
  • 第2个字典:该键代表4个单元格的交集;该值代表4个相邻单元的平均值(见下图)。

在下面的例子(左上面板),其中N具有ID = 0时,第一词典将产生 {'0': (0,1,100,101)}由于细胞被编号为0至99朝向右手侧和0至9900,步骤= 100,向下。第二个字典将产生{'0': 0.775},因为0.775是N的4个相邻单元的平均值。当然,这些字典必须具有与我在2D阵列上具有的“交集”一样多的密钥。

这个如何实现?在这种情况下,字典是最好的“工具”吗?感谢你们!

enter image description here

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] 
      ... 
+1

我不知道这是否可以帮助,但至少我可以告诉你所描述的通常被称为模板算法,它是某种二维有限冲击响应滤波器。如果你有'S'样本,并且给定了你的模式,你应该考虑遍历矩阵从1到S(而不是从0到S)并且应用你描述的任何操作。 – Emilien

+0

这是一个开始:)谢谢! – FaCoffee

回答

1

好,字典实际上可能成为你的案例。

你确定你使用的numpy.array格式是正确的吗?我在API中找不到任何数组((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会打印在这种情况下,排序的字典者优先(字典的定义不排序,但如果他们有一个整型键Python会打印出来整理按键)。但是,您可以像以前一样使用str(count)将其更改回字符串。

我希望这会有所帮助,现在我对数学库不太实用,但是我写的代码应该可以很好地适用于任何您想要作为输入的2D方阵。

+0

你对数组格式绝对正确。我实际上修改了我的代码块,尽管它没有用,因为它没有提到字典...... – FaCoffee

+1

我已经做了最后一次修复,试用代码也应该现在工作。无论如何,如果你找到一种方法来声明你想要这个代码应该工作的数组。 – 2015-10-19 15:31:50

+0

实际上''a'数组来自'numpy.genfromtxt(directoryPath,delimiter =“,”)'行。之后,它被转换成一个列表。 – FaCoffee

1

比方说data是原始的numpy.array,行和列的尺寸为drdc

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

您可以产生Keys作为利润回报和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]) 
+1

如果你的数组非常庞大,使用'Keys'作为函数可以节省大量内存,并且使用'numpy'切片和矢量化可以节省时间。 – toine

+1

好吧,它看起来非常好,但它提供了一些包装,如果我没有错。矩阵输出中的第五行必须读取'[5,6,10,11]'而不是'[4,5,9,10]'。在我的模型中不允许包装。对不起,没有提前指出。 – FaCoffee

+1

正确,我改变了代码 - 在功能键中的整数除法错误行1 – toine