使用numpy获取二维索引的子集

时间:2013-09-25 13:38:56

标签: python numpy scipy

我有包含错误值的二维数据(0表示错误)。我的目标是用最近的邻居替换每个坏的值。

SciPy的NearestNDInterpolator似乎是一种很好的方法。在2-D情况下,它接受一个(点数)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 个答案:

答案 0 :(得分:4)

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

或简单地说:

nonzero_values = data[data!=0]

我最初错过了明显的nonzero_values方法,但感谢@askewchan对此的评论。

答案 1 :(得分:1)

  

所以,我需要得到一些指数和价值观:那些“好”。

如果您创建了坏索引的“掩码”,则可以取消该掩码~,然后使用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]))

答案 2 :(得分:1)

完全解决这个问题的另一种方法是通过一个自动“关闭”这些洞的图像过滤器来运行你的阵列。 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.uint8).reshape(3,3)
>>> a[1,1] = 0

>>> a
array([[1, 2, 3],
       [4, 0, 6],
       [7, 8, 9]], dtype=uint8)

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

>>> a
array([[1, 2, 3],
       [4, 0, 6],
       [7, 8, 9]], dtype=uint8)

a作为输出数组,并在原地完成结束:

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

如果你的零间隙很大,请使用更大的square(或来自skimage.morphology的任何形状)。这种情况(除了依赖性)的缺点是它似乎只适用于uint8