I have some data with 19000 sublists such as :

{"   7.9080000e+01   1.9283193e+04"}

Where the first number is the value for variable A and the second for variable B.

All my attempts to transform this format have failed so far. I think my best guess was using ToExpression unsuccessfully.

How can I transform such lists to a "plottable" format by

  • Changing the String format ?
  • Computing the e ?
  • Import the data differently ?
  • 5
    $\begingroup$ How did you import this data? Import supports this (very common) number format: ImportString["12e3", "Table"] $\endgroup$ – Szabolcs Jan 24 '12 at 16:29
  • $\begingroup$ Can you test Andy Ross and Mr Wizard solutions on your real world problem and see which is faster and post? $\endgroup$ – Mike Honeychurch Jan 24 '12 at 22:18

You should be able to use ReadList on the string contents of each sublist. Here I'm just creating a small list containing three elements identical to the one you provided. The result can be plotted using ListPlot for example.

In[20]:= in = {{"   7.9080000e+01   1.9283193e+04"}, 
               {"   7.9080000e+01   1.9283193e+04"}, 
               {"   7.9080000e+01   1.9283193e+04"}};

In[22]:= Table[ReadList[StringToStream@First[i], Number], {i, in}]

Out[22]= {{79.08, 19283.2}, {79.08, 19283.2}, {79.08, 19283.2}}


Due to the comments I should point out that this Table is going to produce an array that is not packed. This means that the evaluator isn't aware ahead of time that all of the values are a particular type (namely real in this case) and so it is going to lean toward more general methods and is going to consume more memory to store the table.

As the documentation for Developer`ToPackedArray points out, using Developer`ToPackedArray will not change results generated by Mathematica, but can enhance speed of execution and reduce memory usage.

In order to pack the result we can simply use ruebenko's suggestion placing Developer`ToPackedArray@ in front of our Table.


I decided to test whether ImportString proposed by Mr. Wizard or the ReadList approach might be faster. In fairness I separated the ExportString out presuming that the string would already be saved somewhere for importing. It appears that ReadList is much faster at least for the fabricated example I've created here. I'd be curious to see if this is true for 500's data.

In[21]:= data = Table["   7.9080000e+01   1.9283193e+04", {5000}];

In[22]:= Export["numbers.txt", data];

In[23]:= in = Partition[ReadList[StringToStream@Import["numbers.txt", 
              "Plaintext"], Record], 1];

In[24]:= (andyr = Table[ReadList[StringToStream@First[i], Number]
                   , {i, in}]); // AbsoluteTiming

Out[24]= {0.0780015, Null}

In[25]:= str = ExportString[in, "Table"];

In[26]:= (mrwiz = ImportString[str, "Table"]); // AbsoluteTiming

Out[26]= {4.1340795, Null}

In[27]:= andyr === mrwiz

Out[27]= True

I should also point out that this comparison is only fair if we assume that the data is already in memory. If not, the cost for Importing should be factored in to the ReadList approach.

| improve this answer | |
  • 1
    $\begingroup$ You may want to add a couple of Developer`ToPackedArray@ in front of ReadList and Table. $\endgroup$ – user21 Jan 24 '12 at 16:37
  • $\begingroup$ @ruebenko, true. But, why would a novice want to do that? $\endgroup$ – rcollyer Jan 24 '12 at 18:14
  • 1
    $\begingroup$ @ruebenko, I was trying to get you to explain what a packed array is and does for you. $\endgroup$ – rcollyer Jan 24 '12 at 18:54
  • 2
    $\begingroup$ @rcollyer, misunderstood that. The reason is that the OP would possibly benefit from less memory being consumed and a possibly speedier consumption of subsequent commands. $\endgroup$ – user21 Jan 24 '12 at 20:04
  • 1
    $\begingroup$ @Mr.Wizard this question came up recently for me when dealing with a custom file format of mine. With out knowing the length of the data section (an oversight in the format :P), it is often easier to read each line in as a string and process from there. So, it isn't necessarily a one time problem, unfortunately. $\endgroup$ – rcollyer Apr 14 '12 at 16:33

As Szabolcs points out, this may be imported by Import. Here's one way to discover this: assign expr = " 7.9080000e+01 1.9283193e+04", then use ImportString on it with all possible import formats, discard those that return $Failed, and look at the results:

  Quiet[{#, ImportString[expr, #]}] & /@ $ImportFormats,
  x_List /; (Last[x] == $Failed)
 Frame -> All

(you need Quiet because many of the $ImportFormats choke on this string). This produces a long table, in which one finds this (somewhere in the middle):

enter image description here

So Import[file,"Table"] will probably work.

That I found this was easier than finding this information in the documentation is interesting!

| improve this answer | |

I echo Szabolcs's comment that you should probably have done this on acquisition, but now you could use this:

dat = {
   {"   7.9080000e+01   1.9283193e+04"},
   {"   7.9080000e+01   1.9283193e+04"},
   {"   7.9080000e+01   1.9283193e+04"}

ImportString@ExportString[dat, "Table"]
{{79.08, 19283.2}, {79.08, 19283.2}, {79.08, 19283.2}}
| improve this answer | |
  • $\begingroup$ I interpreted the question as "which import format should I have used?" (which you do in fact answer) $\endgroup$ – acl Jan 24 '12 at 16:40
  • $\begingroup$ @acl, and that was actually a better question :-) Makes everything easier ! $\endgroup$ – 500 Jan 24 '12 at 16:59
  • $\begingroup$ @Mr Wizard thank You, While, as suggested, i am now acting on acquisition. ImportString@ExportString is really cool ! $\endgroup$ – 500 Jan 25 '12 at 7:34
  • $\begingroup$ @acl I answered the actual question, which I believe was asking for a quick fix to the immediate problem. $\endgroup$ – Mr.Wizard Jan 25 '12 at 10:54

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.