2
$\begingroup$

I have a data file with fields x y z. When I import it to "data", I get a matrix if the form:

{{193.303, 601.595, 0.001079}, {193.383, 612.928, 0.000071}, {199.129,
   476.9, 0.000828},..,{199.21, 488.223, 0.000761}}

Now z is a function of (x,y) that I need to interpolate. Also, the data (x,y) is unstructured. In order to use the interpolation function, I need to convert the data into a form data1:

{{{193.303, 601.595}, 0.001079}, {{193.383, 612.928}, 0.000071}, {{199.129,
   476.9}, 0.000828},..,{{199.21, 488.223}, 0.000761}}

I'm not sure how to do that. I know I have to use Partition in some way, but it ends up partitioning the data as if it were a list of rows. What I need is to partition the elements within the row.

Thank you for reading.

$\endgroup$
1
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory Tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Commented May 26, 2015 at 0:08

2 Answers 2

4
$\begingroup$
data = 
{{193.303, 601.595, 0.001079}, {193.383, 612.928, 0.000071},
 {199.129, 476.9, 0.000828}, {199.21, 488.223, 0.000761}}

Method 1

{{#1, #2}, #3} & @@@ data
{{{193.303, 601.595}, 0.001079}, {{193.383, 612.928}, 0.000071}, 
   {{199.129, 476.9}, 0.000828}, {{199.21, 488.223}, 0.000761}}

Method 2

{Take[#, 2], Last[#]} & /@ data

Method 3

{Extract[#, {{1}, {2}}], Last[#]} & /@ data

Method 4

{#[[1]], #[[2, 1]]} & /@ (Internal`PartitionRagged[#, {2, 1}] & /@ data)
$\endgroup$
2
$\begingroup$

Let's try to simplify this even further and use a handful of extra keystrokes, they are cheap, to try to make this more understandable for a new user.

Suppose you wanted to write a function that would be given a list of three elements {a, b, c} and you wanted it to return {{a, b}, c}. You might see the similarity between this and what you want to do with your data, but you need to do this to every row in your data. We will get to that in a moment.

Now in Mathematica there are at least twelve different ways of writing anything and at least several of those are completely incomprehensible. Here is one way to do this. Look up Most and Last in the documentation until you can think you understand what this is doing. You might even look up in the tutorials about how to define a function if you need to start with that.

f[v_]:={Most[v],Last[v]};

But you don't want to do that to just one list of three elements, you want to do that to every row in your matrix. The Map function does exactly that, it will take the name of a function and "do that function to every element of a list." You can think about your matrix as a list of rows and your f function will take a row and return the modified result. When Map is done it will give you all those results in a list. So you can write

Map[f, matrix]

and get what you need.

Now back to the twelve ways and saving keystrokes. There are shortcuts and abbreviations you can use in Mathematica to save a keystroke here and there. After a while you begin think that is the way you should write code. That is fine. Here is a method that saves a few keystrokes using # and & notation that does the same thing. But you have to learn anonymous functions and how to write those before this becomes obvious.

matrix = {{193.303, 601.595, 0.001079}, {193.383, 612.928, 0.000071},
          {199.129, 476.9, 0.000828}, {199.21, 488.223, 0.000761}};
Map[{Most[#], Last[#]} &, matrix]

gives

{{{193.303, 601.595}, 0.001079}, {{193.383, 612.928}, 0.000071},
 {{199.129, 476.9}, 0.000828}, {{199.21, 488.223}, 0.000761}}
$\endgroup$
5
  • 1
    $\begingroup$ Or slightly more compactly as {Most[#], Last[#]} & /@ matrix $\endgroup$
    – Bob Hanlon
    Commented May 25, 2015 at 23:58
  • $\begingroup$ Also works: {Drop[matrix, None, -1], matrix[[All, -1]]} // Transpose. $\endgroup$ Commented May 26, 2015 at 0:00
  • $\begingroup$ Saving four characters is really low on my priority list when I'm trying to gently ease a new user into understanding that they can look up and maybe even understand the Map function. # and & has already raised the bar high enough and perhaps even too high for a first step. $\endgroup$
    – Bill
    Commented May 26, 2015 at 0:36
  • $\begingroup$ "ease a new user into understanding" - then I submit that my proposal is less cognitively demanding to the OP. ;) $\endgroup$ Commented May 26, 2015 at 0:36
  • 1
    $\begingroup$ In fact, if you want to avoid Slot, you can use this instead: Composition[Through, {Most, Last}]. $\endgroup$ Commented May 26, 2015 at 1:26

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.