从矩阵中删除 nan 元素
Posted
技术标签:
【中文标题】从矩阵中删除 nan 元素【英文标题】:Removing nan elements from matrix 【发布时间】:2014-09-21 11:38:06 【问题描述】:我有一堆矩阵eq1
、eq2
等,定义如下
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)
其中eq1
、eq2
、eq3
等是大型方阵。如您所见,有许多nan
元素围绕着可绘制值的“块”。我想删除所有 nan
值,同时保持矩阵中有效值块的形状。请注意,这些“块”可以位于eq1
、eq2
矩阵中的任何位置。
我查看了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 元素的主要内容,如果未能解决你的问题,请参考以下文章