Mathematica 导出科学计数法数据
Mathematica 导出数据总是遇到很多坑,总结一下。
个人日常喜欢导出 .csv
格式的文件,即数值用逗号分隔。
常用方法: Export 函数
在 mathemtica 中,最常用的导出函数莫过于
Export
。试举一例
先来创建一组数据
1 | data = Table[{a, 10^-7 a}, {a, 1., 10, 1}] |
输出
1 | {{1., 1.*10^-7}, {2., 2.*10^-7}, {3., 3.*10^-7}, {4., 4.*10^-7}, {5., |
使用 Export
函数导出
1 | SetDirectory[NotebookDirectory[]]; |
test.csv
文件内容
1 | 1.,1.e-7 |
到目前为止都没什么问题,Export 函数能够自动转换 8.e-7
这类科学计数法表示的数据。
挖坑
使用 Export
可以直接导出一个变量,那么在必须要迭代的程序中(并且不知道迭代次数),如何把结果累积在一个变量中呢?跟很多程序语言类似,Append
或者 AppendTo
可以追加内容到一个列表中。这个函数众所周知的问题,就是在数据量太大的时候异常卡慢。我们可以比较一下。
定义一个测试函数,输出不同迭代次数下,使用 AppendTo
追加,以及最终导出数据所需时间
1 | testfunc[num_] := |
观察一下不同迭代次数下的需要耗费的时间
1 | SetDirectory[NotebookDirectory[]]; |
从计算时间上可以看到,耗费时间与迭代次数并非线性增加,因此再操作大型数组的术后
AppendTo
就退下吧。
看到这里好像有点跑题?其实这里主要是想说明:通过
AppendTo
追加数组,最终再使用 Export
自动输出科学计数法的数值的方案不可行。另外,PutAppend
函数也类似,不适用大型数组叠加输出。
填坑
这时候只能想原始一点的办法了,想来 Mathematica 应该会提供类似 c++ 文件流的方式,查找一下帮助文档里面的方案:
1 | str = OpenWrite["test.csv"]; |
但是这时候导出的结果只能用混乱来形容。。。
1 | -7 |
得想办法如何转换成想要的数值格式,在帮助文档
NumberFormat
函数中给出了一个例子,经过(交流群的混乱讨论),加工一下
1 | test = 1.2 10^-7; |
但是注意 WriteString
接收的是字符串格式,加个
ToString
转换一下即可,另外在 1-10
范围内的应该不需要科学计数法表达,再混乱地整理一下,
1 | Num2Str[num_] := |
废话有点多了。。。最终再来测试下速度
1 | testfunc[num_] := |
1 | data = Table[{n, testfunc[n]}, {n, 10000, 100000, 10000}]; |
时间明显减少很多,并且线性更强。对比一下 AppendTo
的结果,感动。
最终敲定,在 Mathematica 循环输出科学计数法数据
1 | (*数值格式转换*) |
群友提供的另外一种转换方式 ToString[1.23*^45, CForm]
懒得补图了,就酱🤣。