比Get [“raggedmatrix.mx”]更快的巨大数据导入?

时间:2011-12-20 22:28:16

标签: wolfram-mathematica

任何人都可以建议替代进口一些 从60个.mx文件列表中获取数字数据(.mx格式),每个文件大约650 MBy?

- 太大而无法在此发布 - 研究问题涉及简单的统计操作 具有两倍的GB数据(大约34)而不是可用的RAM(16)。 为了处理数据大小问题,我只是将事情分开并使用 获取/清除策略来进行数学运算。

它确实有效,但是调用Get["bigfile.mx"]需要相当长的时间,所以我想知道使用BLOB或者PostgreSQL或MySQL以及人们用于数字数据GB的数据库是否会更快。

所以我的问题是: 在Mathematica中处理真正大型数据集导入的最有效方法是什么?

我还没有尝试过,但我认为DataBaseLink的SQLImport会慢于Get["bigfile.mx"]

任何人都有分享的经验吗?

(对不起,如果这不是一个非常具体的编程问题,但它真的会帮助我继续进行耗时的发现 - 找出137个最好的可能性 - 来-tackle-A-问题功能于Mathematica的)。

2 个答案:

答案 0 :(得分:3)

这是一个想法:

你说你有一个参差不齐的矩阵,即一系列不同长度的列表。我假设浮点数。

您可以展平矩阵以获得单个长打包的 1D数组(如果需要,使用Developer`ToPackedArray打包),并分别存储子列表的起始索引。然后在导入数据后重建不规则矩阵。


这里有一个在Mathematica中进行的演示(即导入后),从一个大的扁平列表中提取子列表很快。

data = RandomReal[1, 10000000];

indexes = Union@RandomInteger[{1, 10000000}, 10000];    
ranges = #1 ;; (#2 - 1) & @@@ Partition[indexes, 2, 1];

data[[#]] & /@ ranges; // Timing

{0.093, Null}

或者存储一系列子列表长度并使用Mr.Wizard's dynamicPartition function来完成此操作。我的观点是以平面格式存储数据并在内核中对其进行分区将增加可忽略的开销。


将打包的数组导入为MX文件的速度非常快。我只有2 GB的内存,所以我无法测试非常大的文件,但是我的机器上的打包数组的导入时间总是不到一秒。这将解决导入未打包数据的速度较慢的问题(尽管正如我在主要问题的评论中所说,我无法重现你提到的那种极端缓慢)。


如果BinaryReadList速度很快(它不像现在读取MX文件那么快,但看起来像it will be significantly sped up in Mathematica 9),则可以将整个数据集存储为一个大的二进制文件,需要将其分解为单独的MX文件。然后你可以导入文件的相关部分:

首先制作一个测试文件:

In[3]:= f = OpenWrite["test.bin", BinaryFormat -> True]

In[4]:= BinaryWrite[f, RandomReal[1, 80000000], "Real64"]; // Timing
Out[4]= {9.547, Null}

In[5]:= Close[f]

打开它:

In[6]:= f = OpenRead["test.bin", BinaryFormat -> True]    

In[7]:= StreamPosition[f]

Out[7]= 0

略过前500万条:

In[8]:= SetStreamPosition[f, 5000000*8]

Out[8]= 40000000

阅读500万条目:

In[9]:= BinaryReadList[f, "Real64", 5000000] // Length // Timing    
Out[9]= {0.609, 5000000}

阅读所有剩余的条目:

In[10]:= BinaryReadList[f, "Real64"] // Length // Timing    
Out[10]= {7.782, 70000000}

In[11]:= Close[f]

(为了进行比较,Get通常在不到1.5秒的时间内从MX文件中读取相同的数据。我在WinXP btw上。)


编辑如果你愿意花时间在这上面写一些C代码,另一个想法是创建一个库函数(使用Library Link)来存储映射文件(link for Windows),并将其直接复制到MTensor对象中(MTensor只是一个打包的Mathematica数组,如图库链接的C端所示)。

答案 1 :(得分:1)

我认为两种最佳方法是:

1)在* .mx文件中使用Get,

2)或者读入该数据并将其保存为一些二进制格式,您可以为其编写LibraryLink代码,然后通过它读取内容。当然,这有一个缺点,你需要转换你的MX东西。但也许这是一个选择。

一般来说,使用MX文件非常快。

确定这不是交换问题吗?

修改1 : 然后,您也可以在导入转换器中使用:tutorial/DevelopingAnImportConverter