5
$\begingroup$

I have some matrices that have 0's around them, for example, give such a matrix

MatrixForm[ mat = ArrayPad[{{1, 2, 3}, {0, 0, 0}, {7, 8, 0}}, {{1, 2}, {2, 3}}]]

\begin{array}{cccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 2 & 3 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 7 & 8 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array}

Expect to get {{1, 2, 3}, {0, 0, 0}, {7, 8, 0}}. One way is to use image processing, but it's inefficient

ImageData[ImageCrop[Image[mat]]] // Round

{{1, 2, 3}, {0, 0, 0}, {7, 8, 0}}

Do[ImageData[ImageCrop[Image[mat, "Real"]]] // Round, 10^3] // AbsoluteTiming

Might there be a faster method?

$\endgroup$
3

3 Answers 3

8
$\begingroup$
matrixCrop[mat_?MatrixQ] := 
  Take[mat, ##] & @@ CoordinateBounds@SparseArray[mat]@"NonzeroPositions";

MatrixForm[mat = ArrayPad[{{1, 2, 3}, {0, 0, 0}, {7, 8, 0}}, {{1, 2}, {2, 3}}]]
Do[matrixCrop[mat], 10^5] // AbsoluteTiming

{0.694102, Null}

$\endgroup$
6
$\begingroup$

If the core matrix isn't large, the following should be efficient:

RepeatedTiming@
 Normal@With[{m = SparseArray@mat}, 
   m[[##]] & @@ Span @@@ MinMax /@ Transpose@m@"ExplicitPositions"]
(* {0.0000115352, {{1, 2, 3}, {0, 0, 0}, {7, 8, 0}}} *)

If the core is large, the following should not be bad:

pos = m |-> Position[m, Except@{0 ..}, {1}, 1, Heads -> False][[1, 1]];
mat[[pos@mat ;; -pos@Reverse@mat, 
     pos[mat\[Transpose]] ;; -pos@Reverse[mat\[Transpose]]]] // RepeatedTiming
(* {0.0000268782, {{1, 2, 3}, {0, 0, 0}, {7, 8, 0}}} *)
$\endgroup$
5
$\begingroup$

If there is a built-in function, surely someone will bring it up, but in any case, here is one implementation:

aux1[{}]={};
aux1[l_List]:=If[MatchQ[First[l],{0...}],aux1[Rest[l]],l];
aux2[l_List]:=Reverse[aux1[Reverse[aux1[l]]]];
crop[m_?MatrixQ]:=Transpose[aux2[Transpose[aux2[m]]]];

It works in your example

crop[mat]
(* {{1,2,3},{0,0,0},{7,8,0}} *)

Warning: I have not thought much about how this works with edge cases, matrices that are identically zero, numeric matrices, sparse arrays and all of that. Use at your own risk.

$\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.