# Variable partitioning of the data in the form of "list of lists"

I am looking for a way for variable partitioning of the data in the form of a "list of lists" for interpolating the imported data from excel. The data looks like:

data = {
{{5., 9.53333, 0.057735}, {5., 19.3333, 0.057735}, {5.,29.2667, 0.057735},
{5., 39.0667, 0.11547}, {5., 49., 0.}, {10., 11., 0.}, {10., 22.4, 4.35117*10^-15},
{10., 33.6667, 0.057735}, {10., 45.1, 0.}, {10., 56.3333, 0.11547},
{15., 12.4667, 0.057735}, {15., 25.2667, 0.057735}, {15., 38., 0.1},
{15., 50.9333, 0.057735}, {15., 63.7667, 0.057735}, {20., 13.8333, 0.057735},
{20., 28.1, 0.1}, {20., 42.3667, 0.057735}, {20., 56.5333, 0.057735},
{20., 70.8667, 0.152753}}
}


Now I want to interpolated this data using Interpolation function but the problem is that Interpolation needs the data in the form:

{{5., 9.53333}, 0.057735}, {{5., 19.3333}, 0.057735},...}


f = Interpolation[data[[1]], InterpolationOrder -> 2]


it interpolates but produces a warning as well:

 Interpolation::udeg: Interpolation on unstructured grids is currently only
supported for InterpolationOrder -> 1 or InterpolationOrder -> All.
Order will be reduced to 1.


I would have been happy if the 3D plot of f[x,y] would have been a bit better than this (I hate spikes in the plot):

Overall, I think that the problem can be resolved by supplying "structured grids" to the Interpolation command and that's where I have got stuck. I need to arrange the data as it is required in the Interpolation command. I have also checked Mr Wizard's solution for [dynamic partitioning](Partitioning with varying partition size"list manipulation - Partitioning with varying partition size") but it dose not work (or I must say - I could not make it work) in this case. I have got a feeling that some modification in that will do the job but I do not know the workaround for that.
So the question is how to do that?

There are many ways to repartition the data. Here's one:

data2 = Flatten[data /. {x_, y_, z_} -> {{x, y}, z}, 1]


Then you can interpolate as before:

f = Interpolation[data2, InterpolationOrder -> 1]


Note that I have changed the order to 1 -- this is what the warning was telling you -- with data that is not on a regular grid, you cannot use order greater than 1. The jagged edges are then caused (not by the interpolation) but by the number of points used to plot. So changing the PlotPoints option makes it smoother:

Plot3D[f[x, y], {x, 5, 20}, {y, 9.5, 70}, PlotPoints -> 200]


As Mr Wizard points out, it might be safer to make sure that the replacement rule only applies to the numerical data, hence:

data2 = Flatten[data /. {x_?NumericQ, y_?NumericQ, z_?NumericQ} -> {{x, y}, z}, 1]


would be safer.

• I wouldn't recommend this. You could get a false match with the pattern {x_, y_, z_} causing a nasty bug. You should make the replacement at a specific level or use _?NumericQ. Please see: (6543), (7688), (17497). Commented Sep 25, 2013 at 12:56
• Elegant and perfect. I never used Flatten command like that. Great !! Don't mind it but I can't +1 the reply. Sorry to You, Mr Wizard and Artes. Thanks a lot to all of you. Cheers !! :) Commented Sep 25, 2013 at 13:00
• Thanks for the caution Mr Wizard. Checking out the possibility !! Commented Sep 25, 2013 at 13:03
• Now you get my +1. Commented Sep 25, 2013 at 13:14
• @Om. Have you seen these?: (8458), (20334) Commented Sep 26, 2013 at 12:26

I believe all you need is this:

newdata = {{#, #2}, #3} & @@@ data[[1]]

{{{5., 9.53333}, 0.057735}, {{5., 19.3333}, 0.057735}, {{5., 29.2667}, 0.057735}, . . .


If your data contains multiple sets you can use the long form of Apply and the appropriate levelspec, here {2}:

newdata = Apply[{{#, #2}, #3} &, data, {2}]


Reference:

• I must say that was quick. May be it was easy for you. Thanks a ton. c :) Commented Sep 25, 2013 at 12:56
• @Om. You're welcome. Yes, it was easy, but I spend way too much time playing with Mathematica syntax. :-) I think you will find a lot of power in Slot (#, #2, etc.) which is used in Function (short form &), and Apply. I use these functions all the time. Sometimes they are not optimal due to unpacking but they are convenient and concise, therefore often my first approach. Commented Sep 25, 2013 at 13:02
d = {{#1, #2}, #3} & @@@ Flatten[data, 1]


or

d = {Most @ #, Last @ #}& /@ Flatten[data, 1]


e.g.

{Most@#, Last@#} & /@ Flatten[data, 1] // Short

{{{5., 9.53333}, 0.057735}, <<18>>, {{20., 70.8667}, 0.152753}}


Edit

Given data allow only for InterpolationOrder -> 1

f = Interpolation[ d, InterpolationOrder -> 1];


To visualize data we can make use of various options of Plot3D. To get a better resolution we rescaled z-axis using appropriate values of BoxRatios.

Plot3D[ f[x, y], {x, 5, 20}, {y, 14, 70}, PlotPoints -> 150,  MaxRecursion -> 4,
MeshFunctions -> {#3 &}, Mesh -> 30, ClippingStyle -> None,
ColorFunction -> "DeepSeaColors", BoxRatios -> {15, 60, 5},
ViewPoint -> {-1, -3, 1}]