Получите подмножество двумерных индексов, используя numpy

У меня есть 2-D данные, содержащие плохие значения (0 указывает на плохое). Моя цель - заменить каждое плохое значение ближайшим соседом, что неплохо.

SciPy NearestNDInterpolator кажется хорошим способом сделать это. В двумерном случае он принимает (количество точек) x 2 массива индексов и число (количество точек) x 1 соответствующих значений для интерполяции из.

Итак, мне нужно получить подмножество индексов и значений: те, которые являются "хорошими". Код ниже достигает этого, но coordinates = array(list(ndindex(n_y, n_x))) и where(values != 0)[0] являются грязными. Есть ли более чистый способ сделать это?

# n_y and n_x are the number of points along each dimension.
coordinates = array(list(ndindex(n_y, n_x)))
values = data.flatten()
nonzero_ind = where(values != 0)[0]
nonzero_coordinates = coordinates[nonzero_ind, :]
nonzero_values = values[nonzero_ind]

Спасибо.

3 ответа

nonzero_coordinates = np.argwhere(data != 0)
nonzero_values = np.extract(data, data)

или просто:

nonzero_values = data[data!=0]

Я изначально скорее пропустил очевидный метод nonzero_values, но благодаря @askewchan в комментариях для этого.


Еще один способ приблизиться к этой проблеме - просто запустить ваш массив через фильтр изображений, который автоматически "закрыл" эти отверстия. В scipy.ndimage есть такой фильтр grey_closing:

>>> from scipy import ndimage
>>> a = np.arange(1,26).reshape(5,5)
>>> a[2,2] = 0
>>> a
array([[ 1, 2, 3, 4, 5],
 [ 6, 7, 8, 9, 10],
 [11, 12, 0, 14, 15],
 [16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25]])
>>> a = np.arange(1,26).reshape(5,5)
>>> ndimage.grey_closing(a, size=2)
array([[ 7, 7, 8, 9, 10],
 [ 7, 7, 8, 9, 10],
 [12, 12, 13, 14, 15],
 [17, 17, 18, 19, 20],
 [22, 22, 23, 24, 25]])

Но у этого есть неудачные последствия для края (которые вы можете немного изменить с помощью параматера mode). Чтобы этого избежать, вы можете просто взять новые значения от исходного массива до 0 и поместить их в исходный массив:

>>> np.where(a, a, ndimage.grey_closing(a, size=2))
array([[ 1, 2, 3, 4, 5],
 [ 6, 7, 8, 9, 10],
 [11, 12, 12, 14, 15],
 [16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25]])

В качестве альтернативы вы можете использовать scikit-image:

>>> from skimage.morphology import closing, square
>>> a = np.arange(1,10, dtype=np.*****).reshape(3,3)
>>> a[1,1] = 0
>>> a
array([[1, 2, 3],
 [4, 0, 6],
 [7, 8, 9]], dtype=*****)
>>> closing(a, square(2))
array([[1, 2, 3],
 [4, 4, 6],
 [7, 8, 9]], dtype=*****)
>>> a
array([[1, 2, 3],
 [4, 0, 6],
 [7, 8, 9]], dtype=*****)

Дайте ему a, поскольку выходной массив и закрытие выполняются на месте:

>>> closing(a, square(2), a)
>>> a
array([[1, 2, 3],
 [4, 4, 6],
 [7, 8, 9]], dtype=*****)

Используйте большие square (или любую форму из skimage.morphology), если у вас большие пробелы нулей. Недостатком этого (помимо зависимости) является то, что он работает только для *****.


Итак, мне нужно получить подмножество индексов и значений: те, которые являются "хорошими".

Если вы создали "маску" неудачных индексов, вы можете принять отрицание этой маски ~, а затем найти индексы из маски с помощью np.where. Например:

import numpy as np
# Sample array
Z = np.random.random(size=(5,5))
# Use whatever criteria you have to mark the bad indices
bad_mask = Z<.2
good_mask = ~bad_mask
good_idx = np.where(good_mask)
print good_mask
print good_idx

Дает в качестве примера:

[[ True  True  True  True False]
 [ True False False  True  True]
 [ True False  True  True  True]
 [ True  True  True  True  True]
 [ True  True  True  True  True]]
(array([0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]), array([0, 1, 2, 3, 0, 3, 4, 0, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]))

licensed under cc by-sa 3.0 with attribution.