3
$\begingroup$

I have a dataset that I import from a csv file. It's a rectangular array of values, with the first row and first column specifying the x and y coordinates. I want fit this data to a 2D function using NonlinearModelFit. It seems that for NonlinearModelFit, I need the data in the form {{x1, y1, z1},{x2,y2,z2},...}, but for plotting with ListDensityPlot, it is much faster to use data in the rectangular array form {{z1, z2...},{...},...}. My question is if there is a fast, efficient way to translate between these two data formats. My current solution is to make the coordinate form with something like

coordinateArray = Flatten[Table[{x[[i]], y[[j]], dataArray[[i,j]]},
                                {i,1,Length[x]},{j,1,Length[y]}],1]

and to go back with

dataArray = Partition[coordinateArray[[All, 3]], Length[y]]

These seem to work, but I'm wondering if there's a better way or if there's a way to avoid this altogether with some option of NonlinearModelFit.

$\endgroup$
2
$\begingroup$

The first transformation given in the question.

coordinateArray = Flatten[Table[{x[[i]], y[[j]], dataArray[[i, j]]}, 
    {i, 1, Length[x]}, {j, 1, Length[y]}], 1];

is quite efficient, requiring only 1.6 sec on my PC to transform a million element array. It is, however, possible to obtain the same result more quickly with

coordinateArray = MapThread[Append[#1, #2] &, {Tuples[{x, y}], Flatten[dataArray]}];

which requires only 0.7 sec. (Tuples generates all combinations {x, y}, and Append attaches corresponding z values.) Incidentally, Flatten[Outer[List, x, y], 1] is equivalent to Tuples[{x, y}] and Join[#1, {#2}] & is only about 15% slower than Append[#1, #2] &

The inverse transformation given in the question requires only 0.04 sec, and I have found nothing faster.

$\endgroup$
0
$\begingroup$

I want to address your definition of your table format and the way that you reading the CSV data. From your code, you are reading from sequence item 1. But this is meaningless because the first row and first column do not represent a coordinate position , therefore position {1,1} has no data. here is a demo data to show better my point.

{{ 0, 1, 2, 3}, {1, 3, 6, 0}, {2, 7, -4, 0}, {3, 0, -3, 66}, {4, 0, 
   5, -3}} // MatrixForm

This is the format for a coordinate table you describe.

enter image description here

I exporter and imported this to test your scenario.

In[90]:= Export["jose", %, "CSV"]

Out[90]= "jose"

In[91]:= dataArray = Import["jose"]

Out[91]= {{0, 1, 2, 3}, {1, 3, 6, 0}, {2, 7, -4, 0}, {3, 0, -3, 
  66}, {4, 0, 5, -3}}

Then this table shall be read from the second sequence position.

Flatten[Table[{i, j, dataArray[[i + 1, j + 1]]}, {i, 
   Dimensions@dataArray - 1 // First}, {j, 
   Dimensions@dataArray - 1 // Last}], 1]

{{1, 1, 3}, {1, 2, 6}, {1, 3, 0}, {2, 1, 7}, {2, 2, -4}, {2, 3, 0}, {3, 1, 0}, {3, 2, -3}, {3, 3, 66}, {4, 1, 0}, {4, 2, 5}, {4, 3, -3}}

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