3

I have a list of lists from which I would like to pick out the positions of the number 1 and then print out these positions for each sublist.

I am having some trouble collecting what I am printing into a list / matrix / array though. Below is my list of lists and the commands by which I find the positions of the 1's and print them out. Thanks.

ZeroCrossings = {{0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1,
   0, 0, 1, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
   0}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0}, {0, 0, 0, 1, 0, 0, 
  0, 0, 1, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0}}

Do[Print[Flatten[Transpose[Position[ZeroCrossings[[t]], 1]]]], {t, 1,Length[ZeroCrossings]}]

{3,9}

{4,5,8,12,13}

{4,12,13}

{4,8,11,13}

{4,9,12,13}

{5,6,11}

Syed
  • 52,495
  • 4
  • 30
  • 85
CJ B
  • 33
  • 2

8 Answers8

5

Primarily you just need to use Table instead of Do and Print. Also you can simplify the code:

Table[Flatten @ Position[t, 1], {t, ZeroCrossings}]
{{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12, 13}, {5, 6, 11}}

See Case #2 of: Alternatives to procedural loops and iterating over lists in Mathematica

It may be simpler to use Map:

Flatten @ Position[#, 1] & /@ ZeroCrossings

This is probably a bit advanced for you right now but you could also use:

GatherBy[Position[ZeroCrossings, 1], First][[All, All, 2]]

Or if you are using Mathematica 10:

GroupBy[Position[ZeroCrossings, 1], First -> Last] // Values
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Like you said first, I used Table in place of Do to solve my problem.

    Table[Flatten[Transpose[Position[ZeroCrossings[[t]], 1]]], {t, 1, Length[ZeroCrossings]}]

    Thanks for your help and advice!

    – CJ B Jul 22 '14 at 04:16
5

Another approach:

ZeroCrossings = {{0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 0,
     1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
    0, 1, 1, 0}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0}, {0, 0, 0,
     1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 
    1, 0, 0, 0}};

Map[Last, GatherBy[Position[ZeroCrossings, 1], First], {-2}]

{{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12,
13}, {5, 6, 11}}

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
4
zeroCrossings = {{0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 0,
     1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
    0, 1, 1, 0}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0}, {0, 0, 0,
     1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 
    1, 0, 0, 0}};

Using SequencePosition:

SequencePosition[#, {1}] & /@ zeroCrossings /. {a_, a_} :> a

Using MapIndexed:

MapIndexed[If[#1 == 1, First@#2, Nothing] &, #] & /@ zeroCrossings

{{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12,
13}, {5, 6, 11}}

Syed
  • 52,495
  • 4
  • 30
  • 85
4
SparseArray[ZeroCrossings] @ "AdjacencyLists"
{{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, 
 {4, 9, 12,  13}, {5, 6, 11}}
kglr
  • 394,356
  • 18
  • 477
  • 896
4

You can also use PositionIndex in Version 10

(PositionIndex /@ ZeroCrossings)[[All, 2]]

Gives:

{{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12, 13}, {5, 6, 11}}
RunnyKine
  • 33,088
  • 3
  • 109
  • 176
3
Catenate @* Position[1] /@ ZeroCrossings

{{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12, 13}, {5, 6, 11}}

eldo
  • 67,911
  • 5
  • 60
  • 168
2

Another possibility is to use Position at level -1 and SplitBy as follows:

Map[#[[All, 2]] &, SplitBy[Position[ZeroCrossings, 1, -1], First]]

({{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12, 13}, {5, 6, 11}})

Or using Count and PartitionRagged with Position at level -1:

#[[All, 2]] & /@ Internal`PartitionRagged[Position[#, 1, -1], 
Count[#, 1] & /@ #] &@ZeroCrossings

({{3, 9}, {4, 5, 8, 12, 13}, {4, 12, 13}, {4, 8, 11, 13}, {4, 9, 12, 13}, {5, 6, 11}})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
1

Since @kglr suggested, already, the use of SparseArray here's another way to go about it

Flatten /@ 
 GatherBy[SparseArray[#]["NonzeroPositions"] & /@ ZeroCrossings, 
  First]

{{3, 9}, {4, 5, 8, 12, 13, 4, 12, 13, 4, 8, 11, 13, 4, 9, 12, 13}, {5, 6, 11}}

bmf
  • 15,157
  • 2
  • 26
  • 63