0
$\begingroup$

I would like to export huge numeric datasets in a format suitable for other programming languages. Say, .csv, .txt, and other similar.

Previously, when using versions <= 13.2, I have used ExportTable package from this question. However, once I installed 14.1 (which introduced a lot of bugs in my previously working codes), the package stopped importing properly, and I was left with the extremely slow Export. Okay, it is very fast if exported in the mx format, but it is not widely recognizable.

Is there any workaround nowadays allowing us to export the data fast in Mathematica?

Edit

So, consider a table

tab = RandomReal[{-10,10},{1000,1000}];

The fastest way to export it in Mathematica seems to be the binary format mx:

Export["tab.mx",tab,"MX"];

It takes 0.04 s on my machine.

Exporting in .json format,

Export["tab.json",tab,"JSON"];

is an order of magnitude slower.

Exporting in Table format

Export["tab.txt",tab,"Table"];

is another order of magnitude slower.

I want to maintain the speed of exporting in .mx format but with the final output being easily recognizable by any other framework. Previously, I used ExportTable packaged, but it fails loading in 14.1@Windows 11 (although it worked on 13.2):

<<ExportTable`

LibraryFunction::libload: The function ExportTableG was not loaded from the file C:\Users\miksi\AppData\Roaming\Wolfram\Applications\ExportTable\ExportTable.dll.

The approach referred to by Domen also has some issues, at least at 14.1:

colsep = "\t";
rowsep = "\n";
prec = 16;
SetAttributes[doubletostring, Listable];
doubletostring[x_] := Internal`DoubleToString[x, False, prec];
Export[
    "a.txt",
    StringJoin[
      Map[
        row \[Function] StringJoin[Riffle[doubletostring /@ row, colsep], rowsep],
        tab]
    ]
    ]; // AbsoluteTiming // First

StringJoin::string: String expected at position 1 in InternalDoubleToString[-1.2255,False,16]<> <>InternalDoubleToString[-2.59311,False,16]<> <>InternalDoubleToString[0.999274,False,16]<> <>InternalDoubleToString[-7.61087,False,16]<> <>Internal`DoubleToString[2.91463,False,16]<> <><<1990>>.

Because of this, it looks like the status of this question is unresolved, and no adequate approaches exist.

So, my main question is whether it is possible to fix the ExportTable package. Given my limited knowledge of C++, I cannot do it myself yet. An alternative question is whether some workarounds exist that provide an exporting speed at least within the order of magnitude in a .txt format. On top of that, I am interested in whether it is possible to export mixed data (numbers, strings) very fast if using .txt or .csv formats.

I would be grateful for any help.

$\endgroup$
5
  • 4
    $\begingroup$ Once again, you put no effort to searching the existing questions. #170884, #35371 ... $\endgroup$
    – Domen
    Commented Sep 17 at 21:00
  • $\begingroup$ @Domen : the method exporting in .txt looks like a semi-method, as it exports strings, not numbers, and requires some pre-processing. $\endgroup$ Commented Sep 18 at 12:49
  • $\begingroup$ @Domen : anyway, all these methods are outdated/not working/not maintaining the desired performance compared to the ExportTable package. $\endgroup$ Commented Sep 24 at 6:29
  • $\begingroup$ Internal`DoubleToString isn't available anymore, so you should use Internal`MRealToString instead, and then the code works. $\endgroup$
    – Domen
    Commented Sep 24 at 17:34
  • $\begingroup$ @JasonB. : no it is not. All the proposed methods are still very slow compared to what may have been provided by the native C implementation of exporting. $\endgroup$ Commented Oct 2 at 12:18

1 Answer 1

4
+200
$\begingroup$

Functionality of Export for some formats must be really outdated when using several other functions outperforms it.

I think that nobody at Wolfram has looked at Export format "Table" for quite a long time.

(The third argument of MRealToString is a precision)

tab = RandomReal[{-10, 10}, {1000, 1000}];

Export["exp1.txt", 
  StringJoin[
   Riffle[Riffle[#, "\t"] & /@ 
     Map[Internal`MRealToString[#, False, 17] &, tab, {2}], 
    "\n"]]] // Timing

Export["exp2.txt", tab, "Table"] // Timing

{1.71875, "exp1.txt"}

{10.1719, "exp2.txt"}
$\endgroup$
4
  • 1
    $\begingroup$ This is practically the same answer as the one from Henrik Schumacher in the linked question, but just replacing the obsolete Internal`DoubleToString with Internal`MRealToString. $\endgroup$
    – Domen
    Commented Sep 24 at 17:36
  • 1
    $\begingroup$ @Domen They may look similar but attentive user may observe that my is roughly 1.15 times faster. (I admit it is negligible) The second difference is that Henrik Schumacher's code appends two unnecessary bytes "0D0A" at the end of the file, mine does not. $\endgroup$ Commented Sep 25 at 8:24
  • $\begingroup$ Is it possible to export not using the *^xx format but the exx format? $\endgroup$ Commented Dec 3 at 11:05
  • $\begingroup$ @JohnTaylor I do not see any other way than using StringReplace[Internal`MRealToString[#, False, 17], "*^" -> "e"] & but this slow it considerably. $\endgroup$ Commented Dec 3 at 11:38

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