3
$\begingroup$

I have a matrix A with n columns and matrix B with m < n columns. All columns of B are contained in the columns of A. I want to select those columns in A (the ones which are common in A and B) and remove them such that I am left with n-m columns in A. Is there a way to do this directly in Mathematica?

$\endgroup$
  • 2
    $\begingroup$ Just a warning, you accepted an answer that produces an incorrect result (if your question is correctly phrased). Even after it was changed (to use transpose), it will reorder the columns. $\endgroup$ – Alan Apr 20 '18 at 18:58
1
$\begingroup$

If each element in B was contained in A, thenComplement[A,B] would do fine. For example, suppose A={{1, 2}, {3, 4}, {5, 6}} and B={{1, 2}, {3, 4}}, then it would be Complement[{{1, 2}, {3, 4}, {5, 6}}, {{1, 2}, {3, 4}}], which would give out {{5,6}} -----a correction--------- I mistaken the meaning of the word "column", the correct code should be Transpose@Complement[Transpose@A,Transpose@B]

$\endgroup$
  • $\begingroup$ OP wanted columns, not rows. $\endgroup$ – Nasser Apr 20 '18 at 0:46
  • 2
    $\begingroup$ Complement reorders ... $\endgroup$ – Alan Apr 20 '18 at 0:53
2
$\begingroup$

I'd prefer DeleteCases over replacement rules. Even faster is using Tally in conjunction with Pick.

n = 1000;
m = 100;
idx = RandomChoice[Range[n], m];
A = RandomInteger[{0, 1000}, {n, n}];
B = A[[All, idx]];

a = Transpose[ Transpose[A] /. {x_List /; MemberQ[Transpose[B], x] -> Nothing}]; // 
  RepeatedTiming // First
b = Transpose[DeleteCases[Transpose[A], Alternatives @@ Transpose[B]]]; //
   RepeatedTiming // First
c = Transpose[
     Pick[##, 1] & @@ 
      Transpose[Tally[Join[Transpose[A], Transpose[B]]]]]; // 
  RepeatedTiming // First
a == b == c

0.364

0.018

0.010

True

$\endgroup$
1
$\begingroup$

You can use Fold to delete repeatedly from the transposed list, and transpose back to the original:

Transpose@Fold[DeleteCases, Transpose[A], Transpose[B]]
$\endgroup$
0
$\begingroup$
(* fake data *)
mA = RandomInteger[{0, 1000}, {10, 5}]
mB = mA[[All, {1, 3, 5}]]
(* the answer to your question: *)
Transpose[Transpose[mA] /. {x_List /; MemberQ[Transpose[mB], x] -> Nothing}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.