I have some dataset, which is supposed to have $30000$ in the last column, and I want to find the elements that break this, and arrange them numerically while mantaining the index. What I'm currently doing is finding the exceptions and the indexes separately, then threading and sorting.

nums = Cases[data[[All, -1]], Except[30000]];
index = Flatten@Position[data[[All, -1]], _?(# != 30000 &)];
Sort[Thread[{nums, index}], #1[[1]] < #2[[1]] &]

{{121,200}, {969,37}, ..., {29618,70}, {29934,96}}

I tried to use MapIndexed, but it seemed slower and confusing to me. Is there a less convoluted way?


I would do: SortBy[MapIndexed[ If[# != 30000, {#, First@#2}, Nothing] &, Last/@data ],First]

A little less compact, but equivalent:

myTest[number_,index_]:=If[ number != 30000, {number,index},Nothing];

MapIndexed supplies the index as #2 for you to use in your function, but it comes as a list, so you have remove the head with First.

You could also use Position more directly:

exceptions = {Extract[Last /@ data, #], First@#} & /@ Position[Last /@ data, x_ /; x != 30000]
exceptions = SortBy[exceptions,First]

This could be of some help.

list = data[[All, -1]]; 
Sort@Select[Thread[# -> Range[Length@list]] &@list /. Rule -> List, First[#] != 30000 &]

I took this as the example data:

data = Partition[Riffle[RandomChoice[{"A", "B"}, 10^6], 
    RandomChoice[Range[29000, 31000], 10^6]], {2}];

My code gave 3.2 seconds for RepeatedTiming and yours comes to around 24 seconds. A minor improvement.


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.