2015-01-22 4 views
4

Этот вопрос связан с: How to apply a disc shaped mask to a numpy array?Применение круговой маски с периодическими граничными условиями в Python

из раствора: https://stackoverflow.com/a/8650741/4484153, можно получить круглую маску следующим образом:

>>> new_arr 
array([[ True, True, True, True, 1., 1., 1., True], 
     [ True, True, True, True, True, 1., True, True], 
     [ True, True, True, True, 1., 1., 1., True], 
     [ True, True, True, True, 1., 1., 1., True], 
     [ 1., True, 1., 1., 1., 1., 1., 1. ], 
     [ 1.,  1., 1., 1., 1., 1., 1., 1. ], 
     [ 1., True, 1., 1., 1., 1., 1., 1. ], 
     [ True, True, True, True, 1., 1., 1., True]]) 

в таком способ, которым массив обходит вокруг своих столбцов и строк?

+0

Непонятно, что вы подразумеваете под «получением круговой маски». – farenorth

+0

Кажется, что вы потеряли строку и потеряли столбец, когда вы завернули маску вокруг. Это намеренно? –

+0

ajcr: Это была опечатка, я ее исправил. – MisterJ

ответ

3

Одним из способов может быть только создание маски требуемого размера в центре массива, а затем использовать np.roll для смещения маски вдоль оси (это заставляет маску обтекать края массива).

Следуя методу в связанном вопрос и ответ:

ones = np.ones((8, 8)) 

a, b = 3, 3 
n = 8 
r = 3 
mask = x**2 + y**2 <= r**2 

конструкции mask, как это:

array([[False, False, False, True, False, False, False, False], 
     [False, True, True, True, True, True, False, False], 
     [False, True, True, True, True, True, False, False], 
     [ True, True, True, True, True, True, True, False], 
     [False, True, True, True, True, True, False, False], 
     [False, True, True, True, True, True, False, False], 
     [False, False, False, True, False, False, False, False], 
     [False, False, False, False, False, False, False, False]], dtype=bool) 

Затем прокатные mask два места вверх и два места слева и использовать его на ones .. .

>>> rolled_mask = np.roll(np.roll(mask, -2, axis=0), -2, axis=1) 
>>> ones[rolled_mask] = 255 
>>> ones 
array([[ 255., 255., 255., 255., 1., 1., 1., 255.], 
     [ 255., 255., 255., 255., 255., 1., 255., 255.], 
     [ 255., 255., 255., 255., 1., 1., 1., 255.], 
     [ 255., 255., 255., 255., 1., 1., 1., 255.], 
     [ 1., 255., 1., 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1., 1., 1., 1.], 
     [ 1., 255., 1., 1., 1., 1., 1., 1.], 
     [ 255., 255., 255., 255., 1., 1., 1., 255.]]) 
+0

Спасибо ajcr. Это похоже на то, что мне понадобится :) Единственное беспокойство - мне придется применить эту маскировку для каждого элемента, так что может потребоваться бит вычислительного времени (я буду работать с огромными массивами). Не хватит репутации, иначе бы проголосовали. – MisterJ

+0

Без проблем, рад, что это было полезно! Одна из проблем заключается в том, что 'np.roll' создает новый массив в памяти - если маски огромны, это нежелательно (но все равно должно быть работоспособным). Мощный математический способ выбора требуемых индексов может быть более экономичным. Я отправлю сообщение об обновлении ответа, если мне что-то значительно улучшится ... –

+0

@MisterJ: Похоже, вы можете искать функцию [scipy.ndimage.filters] (http://docs.scipy.org) /doc/scipy/reference/ndimage.html#module-scipy.ndimage.filters). Есть несколько примеров использования generic_filter в [учебнике] (http://docs.scipy.org/doc/scipy/reference/tutorial /ndimage.html#generic-filter-functions). Обратите внимание, в частности, на параметр «footprint», который позволит вам передать * одну круговую маску и переключиться на нее. – unutbu

1

Если y ou хотите создать маску напрямую, следующие работы:

>>> N = 10 
>>> row, col = 8, 7 
>>> radius = 4 
>>> rows = np.arange(N) - row 
>>> rows = np.minimum(np.abs(rows), rows % N) 
>>> cols = np.arange(N) - col 
>>> cols = np.minimum(np.abs(cols), cols % N) 
>>> (rows[:, None]**2 + cols**2 <= radius**2).astype(int) 
array([[1, 0, 0, 0, 1, 1, 1, 1, 1, 1], 
     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1], 
     [0, 0, 0, 0, 0, 0, 0, 1, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 1, 0, 0], 
     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1], 
     [1, 0, 0, 0, 1, 1, 1, 1, 1, 1], 
     [1, 0, 0, 0, 1, 1, 1, 1, 1, 1], 
     [1, 1, 0, 1, 1, 1, 1, 1, 1, 1], 
     [1, 0, 0, 0, 1, 1, 1, 1, 1, 1]]) 
+0

Спасибо Jaime, я тоже попробую это сделать :) Это может помочь мне сократить время вычисления, поскольку оно применяется непосредственно. – MisterJ

Смежные вопросы