2015-10-19 9 views
1

Я довольно новичок в программировании, поэтому прошу прощения, если это классический и тривиальный вопрос. У меня есть 2D-массив 100x100, который строится с помощью matplotlib. На этом изображении каждая ячейка имеет свое значение (от 0.0 до 1.0) и ID (от 0 до 9999, начиная с верхнего левого угла). Я хочу попробовать матрицу с помощью 2х2 окна, которое производит два словарей перемещения:Как образец огромного 2D-массива в Python с использованием массивов 2x2 для создания словаря? (Алгоритм Stencil для Python)

  • первого словарь: ключ представляет собой пересечение 4-клеток; значение представляет кортеж с идентификаторами 4 соседних ячеек (см. изображение ниже - пересечение представлено «N»);
  • 2-й словарь: ключ представляет собой пересечение 4 ячеек; значение представляет собой среднее значение 4 соседних ячеек (см. изображение ниже).

В приведенном ниже примере (верхняя левая панель), где Н имеет ID = 0, 1-ый словарь даст {'0': (0,1,100,101)}, так как клетки пронумерованы от 0 до 99 по направлению к правой стороне и от 0 до 9900, step = 100, меньше. Второй словарь даст {'0': 0.775}, так как 0.775 - это среднее значение 4 соседних ячеек N. Конечно, эти словари должны иметь столько ключей, сколько «пересечений», которые у меня есть на двумерном массиве.

Как это можно сделать? И в этом случае словари являются лучшим «инструментом»? Спасибо вам, ребята!

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

Я не знаю, если это может помочь, но по крайней мере я могу сказать что то, что вы описываете, широко известно как алгоритм трафарета, который является своего рода 2D-фильтром с конечным импульсным откликом. Если у вас есть образцы «S» и заданы ваши шаблоны, вы должны рассмотреть возможность перемещения матрицы от 1 до S (не от 0 до S) и применять любую операцию, которую вы описываете. – Emilien

+0

Это начало :) Спасибо в любом случае! – FaCoffee

ответ

1

Ну, словари могут на самом деле быть в вашем случае.

Вы уверены, что формат numpy.array верен? Я не нашел в API никакой массив ((int, int)). в любом случае ...

Что делать, когда у вас есть 2D массив, объявленный

Чтобы сделать упорядоченный, давайте сделаем две функции, которые будут работать с любой квадратной 2D массива, возвращая два словаря, что вам нужно:

#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") 

по сравнению с первым кодом, я предпочитаемое использованием целого в качестве одного из ключевых причин питона напечатает словарь отсортированный в этом случае (словари по определению Unsorted, но если у них есть ИНТ ключи Python напечатает их отсортированы по ключу). Тем не менее, вы можете изменить его обратно на строку, используя str (count), как и раньше.

Надеюсь, это поможет, теперь я не очень практичен с математическими библиотеками, но код, который я написал, должен хорошо работать с любым двумерным квадратным массивом, который вы можете захотеть поместить в качестве ввода!

+0

Вы абсолютно правы в отношении формата массива. Я действительно исправил свой блок кода, хотя он бесполезен, поскольку он не упоминает dicts ... – FaCoffee

+1

Я сделал последнее исправление, пробный код тоже должен работать сейчас. В любом случае, если вы найдете способ объявить массив, в котором вы хотите, чтобы этот код работал. –

+0

В самом деле, массив 'a' находится в строке' numpy.genfromtxt (directoryPath, delimiter = ",") '. Позже он преобразуется в список. – FaCoffee

1

Скажем, data является оригиналом numpy.array с размером dr и dc для строк и столбцов.

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

Правильно, я изменил код - это была ошибка в делении целого в функции Keys line 1 – toine