从矩阵中删除 nan 元素

Posted

技术标签:

【中文标题】从矩阵中删除 nan 元素【英文标题】:Removing nan elements from matrix 【发布时间】:2014-09-21 11:38:06 【问题描述】:

我有一堆矩阵eq1eq2等,定义如下

from numpy import meshgrid, sqrt, arange
# from numpy import isnan, logical_not

xs = arange(-7.25, 7.25, 0.01)
ys = arange(-5, 5, 0.01)
x, y = meshgrid(xs, ys)

eq1 = ((x/7.0)**2.0*sqrt(abs(abs(x)-3.0)/(abs(x)-3.0))+(y/3.0)**2.0*sqrt(abs(y+3.0/7.0*sqrt(33.0))/(y+3.0/7.0*sqrt(33.0)))-1.0)

eq2 = (abs(x/2.0)-((3.0*sqrt(33.0)-7.0)/112.0)*x**2.0-3.0+sqrt(1-(abs(abs(x)-2.0)-1.0)**2.0)-y)

其中eq1eq2eq3 等是大型方阵。如您所见,有许多nan 元素围绕着可绘制值的“块”。我想删除所有 nan 值,同时保持矩阵中有效值块的形状。请注意,这些“块”可以位于eq1eq2 矩阵中的任何位置。

我查看了Removing nan values from an array 和Removing NaN elements from a matrix 中给出的答案,但这些似乎与我的情况并不完全相关。

【问题讨论】:

“删除”是什么意思? "remove" 就像取出 nan 并将非nan 值保留在矩阵中一样......有点像在制作时切掉所有外壳三明治。 sqrt(abs(abs(x)-3.0)/(abs(x)-3.0)) - 你为什么要这样做? sqrt 内的数组值始终为 1、-1 或 NaN。 我输入您的示例代码得到的矩阵不是正方形 【参考方案1】:

IIUC,您可以使用带有np.isnan 的布尔索引来保留切片。可能有更巧妙的方法可以做到这一点,但从以下内容开始:

>>> eq = np.zeros((5,6)) + np.nan
>>> eq[2:4, 1:3].flat = [1,np.nan,3,4]
>>> eq
array([[ nan,  nan,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,  nan,  nan],
       [ nan,   1.,  nan,  nan,  nan,  nan],
       [ nan,   3.,   4.,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,  nan,  nan]])

您可以使用类似的方式选择包含数据的行和列

>>> eq = eq[:,~np.isnan(eq).all(0)]
>>> eq = eq[~np.isnan(eq).all(1)]
>>> eq
array([[  1.,  nan],
       [  3.,   4.]])

【讨论】:

【参考方案2】:

又短又甜,

eq1_c = eq1[~np.isnan(eq1)]

np.isnan 返回一个布尔数组,可用于索引您的原始数组。取其否定,您将获得非 nan 值。

【讨论】:

是的,我试过了。我只得到一个数组。它不会保留包含所有非nan 值的矩阵的形状。 是的,我明白了。如果你的非 NaN 值不形成方阵,你想发生什么?或者换句话说,如果你的 NaN 值没有在原始矩阵中形成交叉怎么办?更一般地说,这可能是一个问题,即如何在布尔矩阵中识别 True 的方块【参考方案3】:

一种选择是手动遍历网格并检查 Nan 值。 Nan 值很容易发现,因为将其与自身进行比较会导致 False。例如,您可以使用它来将所有 Nan 值设置为 0.0。

for x in xrange(len(eq1)):
    for y in xrange(len(eq1[x])):
        v = eq1[x][y]
        if v!=v:
            eq1[x][y] = 0.0

【讨论】:

以上是关于从矩阵中删除 nan 元素的主要内容,如果未能解决你的问题,请参考以下文章

matlab怎么把元素替换成NAN

删除数组中所需元素之间的不需要的元素

scipy稀疏矩阵:删除所有元素为零的行

从字典的 defaultdict(list) 中删除 nan 值

从 F# 中的列表中删除 nans

从 X 数组中删除 NaN 行以及 Y 中的相应行