0
$\begingroup$

I am having trouble thinking of a code that could do a certain task.

I have 101 lists of numbers (100 distance which range in values from 10 to ~100 and 1 time. All have the same number of elements) that give the distance of an object over time. I need code that can take these 100 lists and find the percentage of them that have 1 minimum, 2 minima, 3 minima etc. below a certain value (in this case 30.)

If anyone could help it would be greatly appreciated.

Edit: Apologies for the lack of clarification. I should have made it clear that I already have the 100 sets of distance data in the form of lists, I don't need to generate them. Here is an image I hope clarifies my situation a bit.

This displays 10 of the 100 distance sets over the time. As you can see they have various numbers of minima. I am trying to write a code that can give the number of tables that have 1 or 2 or 3 etc. minima below the value of 30, so for the above example it would be something like 5 for 1 minimum, 2 for 2, 1 for 3 and 2 for 4. Also, the code would preferably have to work for an arbitrary number of lists, not just 100. Let me know if any additional information is needed.

$\endgroup$

closed as off-topic by m_goldberg, LCarvalho, MarcoB, Alexey Popkov, Bob Hanlon Nov 4 '17 at 14:31

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question cannot be answered without additional information. Questions on problems in code must describe the specific problem and include valid code to reproduce it. Any data used for programming examples should be embedded in the question or code to generate the (fake) data must be included." – MarcoB, Alexey Popkov, Bob Hanlon
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    $\begingroup$ Sample data would make your question clearer. Invert the data to turn minimums into maximums, then use FindPeaks. Count can then be used to find the number of peaks above the inverted threshold. Tally the counts to get their multiplicity. $\endgroup$ – Bob Hanlon Oct 14 '17 at 15:24
  • 1
    $\begingroup$ You are more likely to get an answer if you added more information. Is the time vector truly relevant to this problem? What is your criteria for a discrete minimum? Also, please provide a sample of your data. $\endgroup$ – m_goldberg Oct 14 '17 at 15:25
  • $\begingroup$ Thank you for the reply. I have included a sample of 10/100 of the data sets in the form of listlineplots. $\endgroup$ – Lagiacrus Oct 15 '17 at 6:47
  • $\begingroup$ I think @m_goldberg wanted a sample of your data, not an image of it. I think FindPeaks should work, as Bob Hanlon suggested. $\endgroup$ – b3m2a1 Oct 25 '17 at 18:13
1
$\begingroup$

@BobHanlon already told you how to do this. I will flesh it out a bit. Here is an example dataset:

SeedRandom[1];
data = {
    RandomReal[100, 100],
    Table[50.(1+Sin[x])+2x,{x,Subdivide[0, 20,100]}]
};

plot = ListLinePlot[data, GridLines->{{}, {30}}, GridLinesStyle->Red]

enter image description here

Here is a function to find minima below a threshold:

findMinima[t_][list_] := ScalingTransform[{1,-1}] @ FindPeaks[-list, 0, 0, -t]

Here are the minima of my example dataset:

minima = findMinima[30] /@ data

{{{2., 11.142}, {4., 18.7803}, {6., 6.57388}, {8., 23.1155}, {11., 21.1826}, {14., 24.7495}, {20., 20.8051}, {22., 12.8821}, {30., 16.9013}, {33., 1.18355}, {36., 1.1978}, {42., 26.3269}, {45., 5.53108}, {48., 20.3011}, {53., 18.586}, {56., 19.9524}, {59., 27.8197}, {65., 27.355}, {69., 3.81167}, {79., 20.1479}, {82., 22.0603}, {84., 21.5517}, {87., 1.78401}, {90., 8.95166}, {93., 19.6453}, {96., 11.7225}, {100., 3.70128}}, {{24., 9.51545}, {56., 22.0005}}}

and a plot showing that these points are indeed minima:

Show[plot, Epilog -> {Red, Point @ Catenate @ %552}]

enter image description here

So, a function that does what you want is:

Tally[Length @* findMinima[30] /@ data]

{{27, 1}, {2, 1}}

$\endgroup$
  • $\begingroup$ Thank you very much for the clarification. This did the trick. $\endgroup$ – Lagiacrus Oct 15 '17 at 7:31
1
$\begingroup$

You did not give quite a full description, but here's a guess:

t = 100; (* number of periods *)
n = 25; (* number of elements in each list *)
lists = RandomInteger[{10, 100}, {t, n}];
cts = Count[x_ /; x < 30] /@ lists;
time = Range[100];
ListPlot[Transpose[{time, 100*cts/n}]]

If you really wanted to count just the minima conditional on size for each list, you can change cts to

cts = MapThread[Count[#1, x_ /; x == #2 && #2 < 30] &, {lists, Min /@ lists}]
$\endgroup$

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