2D изменяемый итератор / генератор - PullRequest
1 голос
/ 03 марта 2011

У меня есть матрица NxN, которую я хочу разделить на неперекрывающийся блок KxK.Для каждого блока я хочу присвоить новые значения элементам.

Поскольку это выглядит как хорошее место для генератора, я реализовал:

def extracted_patches(im, top_left, patch_size, grid_size):
    '''Extract patches in row-major order following a specific configuration

    Parameters
    ----------
    im : the input image (2D numpy array)
    top_left : (y,x) coordinate of the top left point (e.g. (3,5))
    grid_size : (cy, cx) how many patches in the y-direction and in the x-direction
    patch_size : (h, w) how many pixels for the size of each patch

    Returns
    -------
    a generator that goes through each patch (a numpy array view) in row-major order
    '''
    for i in xrange(grid_size[0]):
        for j in xrange(grid_size[1]):
            yield im[top_left[0] + patch_size[0]*i : top_left[0] + patch_size[0]*(i+1)
                    ,top_left[1] + patch_size[1]*j : top_left[1] + patch_size[1]*(j+1)]

Затем, когда я пытаюсь изменитьзначение каждого патча, присваивание изменяет значение переменной вместо значения, которое дает генератор

output_im = np.zeros((patch_size[0]*grid_size[0], patch_size[1]*grid_size[1]))        
output_im_it = extracted_patches(output_im, (0,0), patch_size, grid_size)

for i in xrange(grid_size[0]*grid_size[1]):
    output_im_it = np.random.random(patch_size)

Может ли мой генератор быть изменяемым?

1 Ответ

2 голосов
/ 03 марта 2011

Как и в случае с любыми переменными, содержащими массив numpy, для изменения значения, на которое указывает «указатель», необходимо избегать присвоения переменной, а присваивать ее фрагменту. Попробуйте это:

for submat in output_im_it:
     submat[:] = np.random.random(patch_size)

В ответ на ваши изменения: кажется, вы перепутали объект генератора со значениями, которые он дает. Вы не можете назначить на куски самого объекта генератора. Вы можете назначить нарезки массивов numpy, которые вы можете получить, например, с помощью output_im_it.next() или с циклом for, как указано выше.

...