我有包含错误值的二维数据(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]
感谢。
答案 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
。