我想从矩阵A
中删除行。
我要删除的行号存储在数组B
中。
例如:
B=[1,2,3]
表示我要从矩阵A
中删除第1、2和3行。我该如何用Julia语言来做到这一点?
答案 0 :(得分:3)
如果您不想安装任何其他软件包,那么我知道的最新解决方案是:
x = randn(5, 2)
inds_to_remove = [1,3,4]
x[setdiff(1:size(x,1), inds_to_remove), :]
这个问题真正归结为如何反转一组已经提出并回答过here的索引。在链接的问题中,请注意,还有一个InvertedIndices软件包,可用于任意维的集合。
还值得注意的是,如果只想删除一行,那么:
x[1:end .!= i, :]
是一种快速,整洁的解决方案。
答案 1 :(得分:2)
另一种更快(但不太整齐)的可能性是
vcat(deleteat!([A[r,:]' for r in 1:size(A, 1)], inds)...)
即提取行作为向量,删除相关行,变换回矩阵形状。
示例:
julia> A = randn(5, 2)
5×2 Array{Float64,2}:
0.0204771 0.641602
-0.51661 0.0314303
-0.0667214 -1.61672
-0.303866 2.0537
-1.31845 -1.44462
julia> inds = [1,3,4]
3-element Array{Int64,1}:
1
3
4
julia> vcat(deleteat!([A[r,:]' for r in 1:size(A, 1)], inds)...)
2×2 Array{Float64,2}:
-0.51661 0.0314303
-1.31845 -1.44462
请注意,结果矩阵是一个副本,{@ {1}}尚未被修改,就像@ColinTBowers答案中一样。
基准:
A
在后者中,julia> @btime vcat(deleteat!([$(A)[r,:]' for r in 1:size($A, 1)], $inds)...);
405.335 ns (17 allocations: 912 bytes)
julia> @btime $(A)[setdiff(1:size($A,1), 1:3), :]; # @ColinTBowers answer
5.049 μs (58 allocations: 2.16 KiB)
似乎是一个很大的瓶颈:
setdiff
手动实施
在速度上,应将以上所有内容与快速手动实施进行比较。类似于
julia> @btime setdiff(1:size($A,1), $inds)
3.253 μs (40 allocations: 1.59 KiB)
这导致
rmrows(A, inds) = begin
rows, cols = size(A)
out = similar(A, rows-length(inds), cols)
for c in 1:cols
i = 1
for r in 1:rows
if !(r in inds)
@inbounds out[i,c] = A[r,c]
i+=1
end
end
end
out
end
Update1:手动实施
Update2:更快的手动实施