在 Julia 中使用 BitArray 来过滤数组的行

Art*_*Lin 6 julia matrix-indexing

我想过滤矩阵的每一行,a使每一行都包含非负值。

\n

首先,我尝试了这个:

\n
julia> a = [-1 2 3; 4 5 6; -5 3 4; 3 5 5]\n4\xc3\x973 Matrix{Int64}:\n -1  2  3\n  4  5  6\n -5  3  4\n  3  5  5\n\njulia> # Desired Operation after filtering should yield 2x3 matrix, [4 5 6; 3 5 5]\n\njulia> mask1 = a .>= 0\n4\xc3\x973 BitMatrix:\n 0  1  1\n 1  1  1\n 0  1  1\n 1  1  1\n\njulia> a[mask1]\n10-element Vector{Int64}:\n 4\n 3\n 2\n 5\n 3\n 5\n 3\n 6\n 4\n 5\n
Run Code Online (Sandbox Code Playgroud)\n

这第一次尝试使我的矩阵变平。当我执行 [mask1, :] 时,也会发生同样的事情。

\n

我的第二次尝试是这样的(等效逻辑使用 python 的 numpy 工作):

\n
julia> mask2 = minimum(a, dims=2) .>= 0\n4\xc3\x971 BitMatrix:\n 0\n 1\n 0\n 1\n\njulia> a[mask2, :]\n2\xc3\x971 Matrix{Int64}:\n 4\n 3\n
Run Code Online (Sandbox Code Playgroud)\n

当我想要整个第二行和第四行时,我的第二次尝试仅捕获第二行和第四行的第一个元素。请注意,如果我对 mask2 使用等效的布尔数组,我确实得到了所需的结果:

\n
julia> mask3 = [false; true; false; true]\n4-element Vector{Bool}:\n 0\n 1\n 0\n 1\n\njulia> a[mask3, :]\n2\xc3\x973 Matrix{Int64}:\n 4  5  6\n 3  5  5\n
Run Code Online (Sandbox Code Playgroud)\n

那么,进行逐行过滤以将 BitMatrix 转换为 Vector{Bool} 的惯用方法是,还是有更干净的方法?另外,问题的关键是为什么 BitMatrix 只返回一行的一个元素,而 Vector{Bool} 返回整行。

\n

Prz*_*fel 6

一种可能的方式:

\n
julia> a[[all(row.>=0) for row in eachrow(a)], :]\n2\xc3\x973 Matrix{Int64}:\n 4  5  6\n 3  5  5\n
Run Code Online (Sandbox Code Playgroud)\n

另一个:

\n
julia> a[findall(x->all(x .>=0), eachrow(a)), :]\n2\xc3\x973 Matrix{Int64}:\n 4  5  6\n 3  5  5\n
Run Code Online (Sandbox Code Playgroud)\n

您尝试执行的版本minimum是:

\n
julia> a[minimum.(eachrow(a)) .>= 0, :]\n2\xc3\x973 Matrix{Int64}:\n 4  5  6\n 3  5  5\n
Run Code Online (Sandbox Code Playgroud)\n

或遵循 @DNF 建议,这实际上是最好的:

\n
julia> a[all.(>=(0), eachrow(a)), :]\n2\xc3\x973 Matrix{Int64}:\n 4  5  6\n 3  5  5\n
Run Code Online (Sandbox Code Playgroud)\n

  • 看来区别不是 Bit 和 Bool 的区别,而是矩阵和向量的区别。`mask2` 是一个 `BitMatrix`,如果你把它变成一个 `BitVector`,它将返回预期的结果(例如使用 `vec(mask2)`)。我真的不明白为什么 `a[mask2, :]` 返回它的作用。对我来说,看起来应该会出错。 (2认同)