0
$\begingroup$

This is a simple question about slots but I still cant see how to do it after searching stackexchange.

(I'm importing a large data file as text and to convert to numbers I think it'll be quicker to import it all as a list of strings and then apply Internal`StringToDouble to each element rather than using Import "Table". I can relatively quickly importing using Import["file","CSV"] as opposed to Import["file","Table"] which would convert it to data for me but slowly).

So say I have a list of strings test:

test={{"1.e9    2.e9    3.e9    4.e9    5.e9"}, {"1.e10 2.e10   3.e10   4.e10   5.e10"}, {"1.e11    2.e11   3.e11   4.e11   5.e11"}, {"1.e12    2.e12   3.e12   4.e12   5.e12"}}

Then I want to split this into lists of data. For a single line this works:

line=1;
Internal`StringToDouble[StringSplit[test[[line, 1]]][[#]]] & /@ Range@5

But what is the syntax for including a #2 to apply this over all lines?

Internal`StringToDouble[StringSplit[test[[#2, 1]]][[#]]] & /@ Range@5
$\endgroup$
  • 1
    $\begingroup$ Try Map[Internal`StringToDouble, StringSplit @@@ test, {2}] and report back. $\endgroup$ – J. M. will be back soon Feb 25 '16 at 18:12
  • $\begingroup$ Yes! That works. And I tried it on my large file and got timing ~13s compared to 22s using Import with "Table". Great! Now I need to see how to include Alex Nazarovsky's very fast writing routine "Mex_writeMatrix" in Mathematica, (it is written in c, and I use it in matlab instead of the standard formatted output routine. See nazarovsky.ru/2014/08/22/…). Please can you make your comment an answer so I can vote it up? $\endgroup$ – DrBubbles Feb 25 '16 at 18:26
  • $\begingroup$ @J.M. Out of curiosity, is there a way to do this using # and #2 or am I missing the point of slots? $\endgroup$ – DrBubbles Feb 25 '16 at 21:53
  • $\begingroup$ It can be done with slots, sure. As you've seen, they are not really needed, tho. $\endgroup$ – J. M. will be back soon Feb 26 '16 at 1:20
2
$\begingroup$

To settle this:

You need to use level-1 Apply[] with StringSplit[] to replace the list containing a single string with the list produced by StringSplit[]:

StringSplit @@@ test
   {{"1.e9", "2.e9", "3.e9", "4.e9", "5.e9"},
    {"1.e10", "2.e10", "3.e10", "4.e10", "5.e10"},
    {"1.e11", "2.e11", "3.e11", "4.e11", "5.e11"},
    {"1.e12", "2.e12", "3.e12", "4.e12", "5.e12"}}

(More explicitly: Apply[StringSplit, test, {1}].)

You can now use Map[f, matrix, {2}] to map f over the entries of a given matrix. Combining this with the previous line, the final snippet is thus

Map[Internal`StringToDouble, StringSplit @@@ test, {2}]
   {{1.*^9, 2.*^9, 3.*^9, 4.*^9, 5.*^9},
    {1.*^10, 2.*^10, 3.*^10, 4.*^10, 5.*^10}, 
    {1.*^11, 2.*^11, 3.*^11, 4.*^11, 5.*^11},
    {1.*^12, 2.*^12, 3.*^12, 4.*^12, 5.*^12}}
$\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.