3
$\begingroup$

I have a very large 3 dimensional dataset (named pcapdata) that I have broken down for data analysis. There are 7 smaller datasets contained in the main set.

My problem is that the data is arranged in a strange way, where there are 3 different sensors I must account for, and the rows of data alternate between the 3 sensors. After breaking down pcapdata into the 7 smaller datasets, I used pure functions to take the data of each sensor using the Take, and I repeated that 3 times for each sensor

papoints = 
  Take[pcapdata[[#]], {1, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4, 5, 6, 7};
pbpoints = 
  Drop[Take[pcapdata[[#]], {2, Length[pcapdata[[#]]], 3}], -2] & /@ 
    {1, 2, 3, 4, 5, 6, 7};
pcpoints = 
  Take[pcapdata[[#]], {3, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4, 5, 6, 7};

These three lines grab every third row of data, starting from row 1, 2, and 3, respectively. Aside from the Drop function, these lines are about the same, aside from the (1, 2, 3). I was wondering if there were some way to use two pure functions (or something else) to reduce this down to one line. I have seen a few examples using #1 and #2 on this forum as well as mathematica's website. However, I couldn't get this to work on my own since my #1 and #2 were lists.

Any help would be greatly appreciated. If the 3 resulting datasets from these 3 lines were condensed into one variable, it would dramatically reduce the amount of code in other regions of my project.

$\endgroup$
1
$\begingroup$

You can use a single pure function:

ClearAll[f]
f = #[[All, #2 ;; -#2 If[#2 == 2, 3, 1] ;; 3]] &;

{papoints, pbpoints, pcpoints} = f[pcapdata, #]& /@ Range[3]

Alternatively,

ClearAll[f2]
f2[d_, k_] := d[[All, k ;; -k If[k == 2, 3, 1] ;; 3]]
{papoints, pbpoints, pcpoints} = f2[pcapdata, #]& /@ Range[3]
$\endgroup$
1
$\begingroup$

Can you try this?
I believe you'll get the same results..

T[x_] :=Take[s=pcapdata[[#]],{x,Length@s,3}]&/@Range@7
papoints = T[1]
pbpoints = {#}&@@@T[2]
pcpoints = T[3]
$\endgroup$
1
$\begingroup$

This answer is not as sophisticated nor as concise as kglr's, but I think it may be easier to understand.

First, for testing purposes, I contrive some data which I believe has the same structure as yours.

SeedRandom[42]; pcapdata = RandomReal[1, {7, 12, 3}];

Next I repeat your calculations with the test data to get validation set.

papoints =
  Take[pcapdata[[#]], {1, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4,5, 6, 7};
pbpoints =
  Drop[Take[pcapdata[[#]], {2, Length[pcapdata[[#]]], 3}], -2] & /@ {1, 2, 3, 4, 5, 6, 7};
pcpoints =
  Take[pcapdata[[#]], {3, Length[pcapdata[[#]]], 3}] & /@ {1, 2, 3, 4, 5, 6, 7};

Now I do a single computation that computes the first and last result needed and an intermediate result for the second result.

{papts, tmp, pcpts} =
    Table[
      f /@ Range[7], 
      {f, Function[k, Take[pcapdata[[#]], {k, -1, 3}] &] /@ Range[3]}];

Finally, I compute the second needed result.

pbpts = Drop[#, -2] & /@ tmp;

Validation

And @@ {papoints == papts, pbpoints == pbpts, pcpoints == pcpts}

True

$\endgroup$

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.