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$
4
  • 1
    $\begingroup$ Try Map[Internal`StringToDouble, StringSplit @@@ test, {2}] and report back. $\endgroup$ Feb 25, 2016 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, 2016 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, 2016 at 21:53
  • $\begingroup$ It can be done with slots, sure. As you've seen, they are not really needed, tho. $\endgroup$ Feb 26, 2016 at 1:20

1 Answer 1

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 and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.