从矩阵中删除nan元素

0 投票
3 回答
6954 浏览
提问于 2025-04-18 15:16

我有一堆矩阵,比如 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 矩阵的任何地方。

我看过一些关于如何去除数组中的 nan 值的答案,比如 从数组中移除nan值从矩阵中移除NaN元素,但这些似乎并不完全适合我的情况。

3 个回答

0

一种方法是手动遍历整个网格,检查里面是否有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
2

简单明了,

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

np.isnan 会返回一个布尔数组,这个数组可以用来索引你原来的数组。对这个布尔数组取反,你就能得到非nan的值。

3

如果我理解得没错,你可以用布尔索引配合 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.]])

撰写回答