# Delete rows in matrix A that are in matrix B

**URL:** <https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687>\
**Category:** General Usage\
**Tags:** matrices\
**Created:** [March 7, 2023, 5:37pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687 "2023-03-07T17:37:28Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bozaga\_Murat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bozaga_murat/32/34441_2.png) [@Bozaga\_Murat](https://discourse.julialang.org/u/Bozaga_Murat)\
**Post date:** [March 7, 2023, 5:37pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/1 "2023-03-07T17:37:28Z")

</div>

I search for function, what is equal to Matlab with setdiff.

[C,ia] = setdiff(A,B,‘rows’);

Thanks, for every help!

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [March 7, 2023, 5:51pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/2 "2023-03-07T17:51:13Z")

</div>

I think there is no build-in counterpart to `setdiff(A, B, 'rows')`.

You could do it yourself, e.g.

```julia
rows(A) = [A[i,:] for i in axes(A,1) ]

C = setdiff(rows(A),rows(B))

```

If you want a matrix as output

```julia
C = reduce(hcat, C)' # see https://discourse.julialang.org/t/finding-indices-using-setdiff/26930

```

If you also need the indices (and performance does not matter too much):

```julia
ia = [i for i in axes(A,1) if A[i, :] in C ]

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [March 7, 2023, 6:10pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/3 "2023-03-07T18:10:41Z")

</div>

```julia
mapreduce(transpose, vcat,setdiff(eachrow(m1),eachrow(m2)))

```

```julia
sd=setdiff(eachrow(m1),eachrow(m2))
m1[[first(vsd.indices) for vsd in sd],:]

```

```julia
sd=setdiff(eachrow(m1),eachrow(m2))
reinterpret(reshape, Int64, Tuple.([sd...]))'

```

this seems to be the fastest

```julia
let S=Set(eachrow(m2)); m1[[∉(s,S) for s in eachrow(m1)],:]end

```

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [March 7, 2023, 6:13pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/4 "2023-03-07T18:13:09Z")

</div>

One more approach (edited with thanks to @rafael.guerra and @bertschi):

```julia
function setdiffrows(a::AbstractMatrix, b::AbstractMatrix)
    ia = Int[]
    Sb = Set(eachrow(b))
    @views for i in axes(a,1)
        a[i, :] ∉ Sb && push!(ia, i)
    end
    return a[ia, :], ia
end

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 7, 2023, 6:32pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/5 "2023-03-07T18:32:36Z")

</div>

A compact one:

```julia
A = A[eachrow(A) .∉ Ref(eachrow(B)), :]

```

---

<div class="post-metadata">

**Author:** ![Bozaga\_Murat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bozaga_murat/32/34441_2.png) [@Bozaga\_Murat](https://discourse.julialang.org/u/Bozaga_Murat)\
**Post date:** [March 7, 2023, 8:47pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/6 "2023-03-07T20:47:14Z")

</div>

I get different return, if I use the solution from SteffanPL or rafael.guerra. ?!  
I think the reason is setdiff compare the difference in the rows and the solution from rafael ist the right one. But the performance with large Matrix is not fine … sadly!

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [March 7, 2023, 9:18pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/7 "2023-03-07T21:18:07Z")

</div>

Using `setdiff(rows(A), rows(B))` considers `rows(A)` as a set, i.e., removes duplicate rows when these are not in `rows(B)`.  
The solution which does not do that can be made quite a bit faster via

```julia
A = A[eachrow(A) .∉ Ref(Set(eachrow(B))), :]

```

as lookup in a set is (obviously) much faster than in an iterable.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 7, 2023, 10:17pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/8 "2023-03-07T22:17:44Z")

</div>

@PeterSimon’s code performs much better for large matrices by using `Set` too.

> **edited code**
>
> ```julia
> function setdiffrows(a::AbstractMatrix, b::AbstractMatrix)
> ia = Int[]
> Sb = Set(eachrow(b))
> @views for i in axes(a,1)
> a[i, :] ∉ Sb && push!(ia, i)
> end
> return a[ia, :], ia
> end
> 
> ```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 7, 2023, 11:11pm UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/9 "2023-03-07T23:11:29Z")

</div>

I will let Peter edit his post and I have marked it as the solution, with special credit to bertschi.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [March 8, 2023, 9:16am UTC](https://discourse.julialang.org/t/delete-rows-in-matrix-a-that-are-in-matrix-b/95687/10 "2023-03-08T09:16:53Z")

</div>

a comparison between the correct and fast solutions

```julia
m1=rand(1:5, 10^6,10);
m2=rand(1:5, 10^6,10);
function setdiffrows(a::AbstractMatrix, b::AbstractMatrix)
    ia = Int[]
    Sb = Set(eachrow(b))
    @views for i in axes(a,1)
        a[i, :] ∉ Sb && push!(ia, i)
    end
    return a[ia, :] #, ia
end
julia> function dr(m1,m2)
           #S=Set(eachrow(m2))
           S=Set(@view m2[r,:] for r in axes(m2,1))
           return @view m1[[∉(s,S) for s in eachrow(m1)],:]
       end 
dr (generic function with 1 method)

julia> @btime dr($m1,$m2);
  479.037 ms (11 allocations: 89.84 MiB)

julia> @btime setdiffrows($m1,$m2); 
  521.005 ms (23 allocations: 160.63 MiB)

```
