请问有什么方便的方法删除数组里Nan所在的行或列


#1

如题,含NaN的数组一般如何处理

julia> C = [1 2;3 4;NaN NaN]
3×2 Array{Float64,2}:
   1.0    2.0
   3.0    4.0
NaN    NaN

使用filter之后就不会保持多维的形状,而是变成列向量。

julia> filter(!isnan,C)
4-element Array{Float64,1}:
 1.0
 3.0
 2.0
 4.0

#2

另外补充个,如何做NaN的替换呢?

julia> C = [1 2;3 4;NaN NaN]
3×2 Array{Float64,2}:
   1.0    2.0
   3.0    4.0
 NaN    NaN

julia> C
3×2 Array{Float64,2}:
   1.0    2.0
   3.0    4.0
 NaN    NaN

julia> findall(isnan, C)
2-element Array{CartesianIndex{2},1}:
 CartesianIndex(3, 1)
 CartesianIndex(3, 2)

julia> C[findall(isnan, C)]
2-element Array{Float64,1}:
 NaN
 NaN

julia> C[findall(isnan, C)] .= .0
2-element view(::Array{Float64,2}, CartesianIndex{2}[CartesianIndex(3, 1), CartesianIndex(3, 2)]) with eltype Float64:
 0.0
 0.0

julia> C
3×2 Array{Float64,2}:
 1.0  2.0
 3.0  4.0
 0.0  0.0

#3

如果是缺失值的话就用 replace(C, NaN=>missing), 删除行或列一定会改变形状。


#4

谢谢,引用的例子里代码示例不是基于0.7+版本,对应的一些操作要使用点操作进行广播。但是这里有点问题,我文档还没有看完,理解还不够。

julia> A = rand(5, 4); A[rand(1:end,4)] .= NaN; A
5×4 Array{Float64,2}:
 NaN           0.464128  NaN           0.837873
   0.913086    0.783489    0.864419    0.438408
   0.601951  NaN           0.460722  NaN
 NaN           0.528835    0.789918  NaN
   0.636599    0.939888    0.57624     0.154921

julia> nanrows = any(isnan.(A),dims=2)
5×1 BitArray{2}:
  true
 false
  true
  true
 false

到这里还没有问题,只是0.7以上版本的any需要明确写出dims=n
但是我执行下一句就会报错。

julia> A[!vec(nanrows),:]
ERROR: MethodError: no method matching !(::BitArray{1})
Closest candidates are:
  !(::Missing) at missing.jl:79
  !(::Bool) at bool.jl:35
  !(::Function) at operators.jl:853
Stacktrace:
 [1] top-level scope at none:0

我觉得是没有广播进去尝试用A[@. !vec(nanrows),:]A[!.vec(nanrows),:]都会报错。
但是我在REPL里利用ans一步一步来就能成功。。。

julia> vec(ans)
5-element BitArray{1}:
  true
 false
  true
  true
 false

julia> @. !ans
5-element BitArray{1}:
 false
  true
 false
 false
  true

julia> A[ans,:]
2×4 Array{Float64,2}:
 0.913086  0.783489  0.864419  0.438408
 0.636599  0.939888  0.57624   0.154921

#5
  1. A[@. !vec(nanrows),:] 出错是因为@.会把后面的表达式全都当作输入吧?(我猜的) 可以看下文档 http://docs.juliacn.com/latest/manual/metaprogramming/#Macro-invocation-1

  2. !的broadcast稍稍有点不一样

  julia> .![true false true]
  1×3 BitArray{2}:
   false  true  false

#6

哇成功了谢谢,是不是前缀运算符都需要放在前面使用点操作。


#7
julia> C = [1 2;3 4;NaN NaN];

julia> hcat((filter(!isnan, C[:, i]) for i in 1:size(C, 2))...)
2×2 Array{Float64,2}:
 1.0  2.0
 3.0  4.0

#8

hcat只能对filter之后每列的数量相等才可以,比如第一列1一个Nan,第二列1个Nan;
对随机的Nan个数不适合,比如第一列1一个Nan,第二列2个Nan


#9

。。。当然了,要不然用 filter 不就行了