1
$\begingroup$

I have the data

{{0, 10, 10}, {0.01829, 12, 10}, {0.0523236, 11, 10}, {0.0616182, 11, 9}, 
{0.0860192, 10, 9}, {0.37603, 12, 9}, {0.405224, 11, 9}, {0.415151, 11, 8}, 
{0.453143, 13, 8}, {0.481562, 12, 8}, {0.482285, 11, 8}, {0.490412, 10, 8}, 
{0.492742, 10, 7}, {0.558841, 9, 7}, {0.602336, 8, 7}, {0.683204, 8, 6}, 
{0.738865, 9, 7}, {0.766657, 9, 9}, {0.780627, 9, 8}, {0.900705, 9, 10}, 
{0.905607, 9, 9}, {0.926086, 9, 8}, {1.00437, 9, 7}, {1.01303, 11, 7}, 
{1.06747, 10, 7}, {1.07523, 9, 7}, {1.33235, 8, 7}, {1.51981, 7, 8}, 
{1.61516, 6, 8}, {1.66955, 6, 7}, {1.95405, 5, 7}, {2.04023, 5, 6}, 
{2.04605, 5, 5}, {2.23846, 5, 4}, {2.25056, 4, 4}, {2.27559, 3, 4}, 
{2.5348, 2, 5}, {2.55095, 2, 6}, {2.71852, 2, 5}, {2.95299, 4, 5}, 
{3.23626, 6, 5}}

which represents {time, amount1, amount2}. Changes to each amount only happens at the times stated in the results.

How do I transform my data so it tells me the two amounts for discrete moments in time?

For example, for steps of 0.5, the data would be the following

{0, 10, 10}, {0.5, 10, 7}, {1.0, 9, 8}, {1.5, 8, 7}, 
{2.0, 5, 7}, {2.5, 3, 4}, {3.0, 4, 5}

For example, for steps of 1, the data would be the following

{0, 10, 10}, {1, 9, 8}, {2, 5, 7}, {3, 4, 5}
$\endgroup$
1

2 Answers 2

1
$\begingroup$

Can use TimeSeries and TimeSeriesResample:

pts = Dataset[{{0, 10, 10},...,{3.23626, 6, 5}}];

Wrap cols 2 and 3 in a List and then TimeSeries

ts = pts[All,{1,{2,3}}][TimeSeries];

Resample:

ts // TimeSeriesResample[#, 0.5] & // #["Path"] &

{{0., {10., 10.}}, {0.5, {9.8902, 7.}}, {1., {9., 7.05582}}, {1.5, {7.10568, 7.89432}}, {2., {5., 6.46681}}, {2.5, {2.13425, 4.86575}}, {3., {4.33191, 5.}}}

Note, from ref page:

"By default, values at intermediate times are computed using first-order interpolation"

Other interpolation methods are available, eg:

ts // TimeSeriesResample[#, 0.5, 
    ResamplingMethod -> {"Interpolation", 
      InterpolationOrder -> 0}] & // #["Path"] &

{{0., {10, 10}}, {0.5, {10, 7}}, {1., {9, 8}}, {1.5, {8, 7}}, {2., {5, 7}}, {2.5, {3, 4}}, {3., {4, 5}}}

$\endgroup$
7
  • $\begingroup$ This method will not give me integers values will it? @alancalvitti $\endgroup$
    – Mlo27
    Mar 24, 2018 at 16:09
  • $\begingroup$ @Mlo27, it does if the input values are integers and InterpolationOrder->0 is chosen - see last line in my answer. (Obviously the time values you wanted are resampled at 0.5 so are not going to be integers). $\endgroup$ Mar 24, 2018 at 16:19
  • $\begingroup$ The time values do not have the be integers. I just need the output to always be integers. Will this method allow that? @alancalvitti $\endgroup$
    – Mlo27
    Mar 24, 2018 at 16:24
  • $\begingroup$ @Mlo27, yes, as I said, read the last line of output. You can use Flatten to get the same verbatim format as in your Q, but that will interfere with any subsequent TimeSeries operations. $\endgroup$ Mar 24, 2018 at 16:27
  • $\begingroup$ Sorry didn’t see that last bit. Thanks for the advice, I’ll give it a try later on :D $\endgroup$
    – Mlo27
    Mar 24, 2018 at 16:33
0
$\begingroup$

You can use a modification of StepFunction from my answer to How can the behavior of InterpolationOrder->0 be controlled?:

StepFunction[data_] := Module[{sdata, nf}, sdata=Sort@data;
    nf = Nearest[sdata[[All,1]] -> "Index"];
    StepFunction[nf, sdata[[All,1]], sdata[[All, {2,3}]], {-1,0}]
]

StepFunction[nf_NearestFunction, x_, y_, clip_][pt_List] := With[
    {near = nf[pt][[All,1]]},
    Join[
        List/@pt,
        y[[Clip[near + Clip[Sign[Subtract[pt, x[[near]]]], clip], {1, Length[x]}]]],
        2
    ]
]
StepFunction[nf_NearestFunction, x_, y_, clip_][pt_] := With[
    {near = First@nf[pt]},
    Prepend[
        y[[Clip[near + Clip[Sign[Subtract[pt, x[[near]]]], clip], {1, Length[x]}]]],
        pt
    ]
]

For your data:

sf = StepFunction[{
    {0,10,10},{0.01829,12,10},{0.0523236,11,10},{0.0616182,11,9},{0.0860192,10,9},
    {0.37603,12,9},{0.405224,11,9},{0.415151,11,8},{0.453143,13,8},{0.481562,12,8},
    {0.482285,11,8},{0.490412,10,8},{0.492742,10,7},{0.558841,9,7},{0.602336,8,7},
    {0.683204,8,6},{0.738865,9,7},{0.766657,9,9},{0.780627,9,8},{0.900705,9,10},
    {0.905607,9,9},{0.926086,9,8},{1.00437,9,7},{1.01303,11,7},{1.06747,10,7},
    {1.07523,9,7},{1.33235,8,7},{1.51981,7,8},{1.61516,6,8},{1.66955,6,7},{1.95405,5,7},
    {2.04023,5,6},{2.04605,5,5},{2.23846,5,4},{2.25056,4,4},{2.27559,3,4},{2.5348,2,5},
    {2.55095,2,6},{2.71852,2,5},{2.95299,4,5},{3.23626,6,5}
}];

Then:

sf[Range[0, 3, .5]]
sf[Range[0, 3]]

{{0., 10, 10}, {0.5, 10, 7}, {1., 9, 8}, {1.5, 8, 7}, {2., 5, 7}, {2.5, 3, 4}, {3., 4, 5}}

{{0, 10, 10}, {1, 9, 8}, {2, 5, 7}, {3, 4, 5}}

$\endgroup$
3
  • $\begingroup$ This method isn't producing an output @Carl Woll $\endgroup$
    – Mlo27
    Mar 24, 2018 at 18:37
  • $\begingroup$ @Mlo27 If you are using M10 or earlier, replace "Index" with Automatic. $\endgroup$
    – Carl Woll
    Mar 24, 2018 at 19:35
  • $\begingroup$ @CarlWoll How can I modify your code for this question. Suggested method is very slow for large data. mathematica.stackexchange.com/questions/172298/… $\endgroup$ May 1, 2018 at 23:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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