4
$\begingroup$

I'd like a more efficient way of doing the following:

I have xyz data in the form of MyList for which I'd like to plot z as a function of x, split by y.

MyList = {
   {1, 1, 0.3}, {2, 1, 0.4}, {3, 1, 0.5},
   {1, 2, 0.7}, {2, 2, 0.85}, {3, 2, 0.9}
   };

List1 = MyList[[1 ;; 3, {1, 3}]];
List2 = MyList[[4 ;; 6, {1, 3}]];

ListLinePlot[{List1, List2}]

The best I've come up with is

NewList = SplitBy[MyList, Part[#, 2] &][[All, All, {1, 3}]]
ListLinePlot[NewList]

which seems very inefficient.

$\endgroup$
0
4
$\begingroup$

This seems to be faster than the method in OP for large inputs:

TakeList[MyList[[All, {1, 3}]], Length /@ Split[MyList[[All, 2]]]]
 {{{1, 0.3}, {2, 0.4}, {3, 0.5}}, {{1, 0.7}, {2, 0.85}, {3, 0.9}}}
SeedRandom[1]
ml = RandomInteger[10, {100000, 3}];

nl1 = SplitBy[ml, Part[#, 2] &][[All, All, {1, 3}]]; // RepeatedTiming // First
 0.23
nl2 = TakeList[ml[[All, {1, 3}]], Length /@ Split[ml[[All, 2]]]]; // 
  RepeatedTiming // First
   0.057
nl1 == nl2
 True

If the input list is already ordered by the second column (as in the example in OP) you can also use GatherBy + Extract and GroupBy

SeedRandom[1]
ml = SortBy[#[[2]] &] @ RandomInteger[10, {100000, 3}];

nl1 = SplitBy[ml, Part[#, 2] &][[All, All, {1, 3}]]; // 
  RepeatedTiming // First
 0.22
nl2 = TakeList[ml[[All, {1, 3}]], Length /@ Split[ml[[All, 2]]]]; // 
  RepeatedTiming // First
 0.0073
nl3 = Extract[ml[[All, {1, 3}]], List /@ GatherBy[Range@Length@ml, ml[[#, 2]] &]]; // 
  RepeatedTiming // First
0.011
nl4 = Values @ GroupBy[ml, #[[2]] &, #[[All, {1, 3}]] &]; // 
  RepeatedTiming // First
 0.0065
nl5 = Values @ GroupBy[ml, (#[[2]] &) -> ( #[[{1, 3}]] &)]; // 
  RepeatedTiming // First (* the version from MarcoB's answer *)
  0.027
nl1 == nl2 == nl3 == nl4 == nl5
True
$\endgroup$
4
$\begingroup$
GroupBy[MyList, (#[[2]]&) -> (#[[{1,3}]]&)] // Values // ListLinePlot

enter image description here

$\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.