3

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

SciPyNearestNDInterpolator似乎是一个不错的方法。在二维情况下,它接受一个(点数)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]

谢谢。

4

3 回答 3

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

或者简单地说:

nonzero_values = data[data!=0]

我最初宁愿错过了明显的nonzero_values方法,但感谢@askewchan 在评论中的评论。

于 2013-09-25T13:59:28.307 回答
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]))
于 2013-09-25T13:56:00.560 回答
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.

于 2013-09-25T16:05:56.580 回答