Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a matrix:

enter image description here

I would like to sum all the first non-zero elements of each row so that I get a value of

$$25.5317 + 8.85471 + 6.90018 + 32.9436 + ... $$

and so on and simply ignore zero rows.

Similarly I would like to do the same again for the second non-zero elements from each row so that I get:

$$29.1235 + 11.0472 + 41.2639$$

share|improve this question
add comment

3 Answers 3

up vote 5 down vote accepted
 tbl = RandomChoice[{.5, .1, .05, .05, .05, .05, .05, .05, .05, .05} ->
     Range[0, 9], {10, 10}];
 tbl//TableForm

enter image description here

Remove all zeros from tbl and add zeros to the right to make a full array:

PadRight[tbl /. (0) -> Sequence[], Automatic] // TableForm

enter image description here

Then sum each column:

 Tr /@ (Transpose@PadRight[tbl /. (0) -> Sequence[], Automatic])
 (* {55, 59, 36, 28, 38, 14, 9} *)

Update: To get a matrix with dimensions {nrows, ncolumns} from PadRight change Automatic to {nrows, ncolumns}. So,

 Tr /@ (Transpose@PadRight[tbl /. (0) -> Sequence[], {10,10}])
 (* {55, 59, 36, 28, 38, 14, 9, 0 ,0, 0} *)
share|improve this answer
    
Hi @kguler, seems to work but I originally had 5 columns, now after sorting, it is 4 columns? Why is that? I need to maintain the column to be constant. –  sebastian c. Nov 16 '12 at 2:27
    
@sebastian, to get a matrix with dimensions {nrows, ncolumns} from PadRight change Automatic to {nrows, ncolumns}. (The setting Automatic adds as many columns as needed to remove raggedness.) –  kguler Nov 16 '12 at 2:37
    
thanks for your clarification. –  sebastian c. Nov 16 '12 at 2:47
add comment

Not as nice as the method given by kguler. Nevertheless, as an alternative:

myarray = {{0., 0., 0., 0., 0}, {0., 0., 0., 0., 0},
  {0., 0., 0., 25.5317, 29.1235}, {0., 0., 0., 0., 8.85471}, {0., 0., 
   0., 0., 0}, {0., 0., 0., 0., 0}, {0., 0., 0., 0., 6.90018}, {0., 
   0., 0., 0., 32.9436}, {0., 0., 0., 0., 29.1235}, {0., 0., 0., 
   2.47854, 11.0472}, {0., 0., 16.1408, 41.2639, 45.7614}, {0., 0., 
   0., 0., 0}, {0., 0., 0., 0., 0}, {0., 0., 0., 0., 0}}

(Using Flatten to transpose a ragged array):

Flatten[Select[#, FreeQ[#, 0. | 0] &] & /@ myarray, {2}]

=>

{{25.5317, 8.85471, 6.90018, 32.9436, 29.1235, 2.47854, 16.1408}, {29.1235, 11.0472, 41.2639}, {45.7614}}

Therefore,

Total /@ Flatten[Select[#, FreeQ[#, 0. | 0] &] & /@ myarray, {2}]

=>

{121.973, 81.4346, 45.7614}

Comparing with kguler's method

tbl = RandomChoice[{.5, .1, .05, .05, .05, .05, .05, .05, .05, .05} ->
     Range[0, 9], {10, 10}];
Tr /@ (Transpose@PadRight[tbl /. (0) -> Sequence[], Automatic]) == 
 Total /@ Flatten[Select[#, FreeQ[#, 0. | 0] &] & /@ tbl, {2}]

=>

True

Edit

Better, perhaps, is

Total /@ Flatten[DeleteCases[myarray, 0 | 0., 2], {2}]

However, the best variation on the Flatten approach, I recon, is given below (as a comment) by rm -rf:

Total[Flatten[# /. 0 | 0. -> Sequence[], {2}], {2}] &@myarray

=>

{121.973, 81.4346, 45.7614}

share|improve this answer
1  
I was about to write an answer with this same approach. It can also be written as: Total[Flatten[# /. 0|0. -> Sequence[], {2}], {2}]& –  rm -rf Nov 15 '12 at 18:42
    
@rm -rf. That is a nice one! Thanks. –  TomD Nov 15 '12 at 19:52
    
Tom and @rm-rf, actually I like your method better:). –  kguler Nov 16 '12 at 3:12
add comment

One can search for the first nonzero element in each row using Cases. Generate a random table:

m = Normal@SparseArray[
      Thread@{RandomInteger[{1, 12}, 14], RandomInteger[{1, 6}, 14]} :> RandomReal[], {12, 6}];

Mathematica graphics

and pick the first match in each row:

Flatten[Cases[#, _?(! PossibleZeroQ@# &), 1, 1] & /@ m]

Or extending the Sequence replacement method in kguler's answer:

m /. {0 | 0. -> Sequence[]} /. {} -> Sequence[] /. {x_?NumberQ, ___} :> x
{0.252222, 0.998427, 0.0562231, 0.849365, 0.582891, 0.0896831, 0.31189, 0.524075}

To get the second nonzero element from each row:

m /. {0 | 0. -> Sequence[]} /. {} | {_} -> Sequence[] /. {_?NumberQ, x_, ___} :> x
{0.949761, 0.841579, 0.0275406, 0.500705}

Total then does the summing.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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