Wolfram mathematica 比Get[“raggedmatrix.mx”更快的海量数据导入速度?

Wolfram mathematica 比Get[“raggedmatrix.mx”更快的海量数据导入速度?,wolfram-mathematica,Wolfram Mathematica,有谁能给我们提供一个替代方案来代替进口一些 从60个.mx文件列表中获取的GB数字数据(以.mx格式),每个文件大约650 MB 这个研究问题太大了,无法在这里发表。它涉及到简单的统计操作 其GB数据量(约34 GB)是可用RAM(16 GB)的两倍。 为了处理数据大小问题,我只需将数据拆分并使用 一个获得/明确的数学策略 它确实可以工作,但是调用Get[“bigfile.mx”]需要相当长的时间,所以我想知道在PostgreSQL或MySQL中使用BLOB或任何东西,或者人们用于GB数字数据的

有谁能给我们提供一个替代方案来代替进口一些 从60个.mx文件列表中获取的GB数字数据(以.mx格式),每个文件大约650 MB

这个研究问题太大了,无法在这里发表。它涉及到简单的统计操作 其GB数据量(约34 GB)是可用RAM(16 GB)的两倍。 为了处理数据大小问题,我只需将数据拆分并使用 一个获得/明确的数学策略

它确实可以工作,但是调用
Get[“bigfile.mx”]
需要相当长的时间,所以我想知道在PostgreSQL或MySQL中使用BLOB或任何东西,或者人们用于GB数字数据的任何数据库,是否会更快

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

我还没有尝试过,但我认为从DataBaseLink导入SQLImport将比
Get[“bigfile.mx”]

有人有一些经验可以分享吗


(很抱歉,如果这不是一个非常具体的编程问题,但它确实会帮助我继续进行耗时的查找137种可能性中最好的是什么,以解决Mathematica中的一个问题)。

我认为最好的两种方法是:

1) 在*.mx文件上使用Get

2) 或者读入数据并以二进制格式保存,然后编写LibraryLink代码并通过该格式读取数据。当然,这有一个缺点,那就是你需要转换你的MX文件。但也许这是一种选择

一般来说,使用MX文件的速度相当快

您确定这不是交换问题吗

编辑1: 然后,您还可以在导入转换器中使用write:

以下是一个想法:

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

您可以展平矩阵以获得单个长压缩1D数组(必要时使用
Developer`topackedaray
对其进行打包),并分别存储子列表的起始索引。然后在导入数据后重建参差不齐的矩阵


这里演示了在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}
或者,存储子列表长度的序列,并使用正是这样做的。我的观点是,以平面格式存储数据并在内核中对其进行分区会增加可以忽略不计的开销


将压缩阵列作为MX文件导入非常快。我只有2GB的内存,因此无法在非常大的文件上进行测试,但对于我的机器上的压缩阵列,导入时间始终只有几分之一秒。这将解决导入未打包的数据可能会变慢的问题(尽管正如我在关于主要问题的评论中所说的,我无法重现您提到的那种极端缓慢)


如果
BinaryReadList
的速度很快(现在没有读取MX文件那么快,但看起来像),则可以将整个数据集存储为一个大的二进制文件,而无需将其拆分为单独的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
In[9]:= BinaryReadList[f, "Real64", 5000000] // Length // Timing    
Out[9]= {0.609, 5000000}
阅读500万条:

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

Out[8]= 40000000
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。)



编辑如果您愿意花时间在这方面,并编写一些C代码,另一个想法是创建一个库函数(使用),该函数将内存映射文件(),并将其直接复制到
MTensor
对象中(从库链接的C端看,
MTensor
只是一个压缩的Mathematica数组)。

?另一个。@yoda注意到Rolf使用的是MX,这是Mathematica的原生二进制格式,在我看来,使用
Import
/
ReadList
比任何其他格式都快。我不知道关于
BinaryReadList
…@Rolf+1的内容,非常相关的问题。它不回答你,但你肯定会感兴趣的。Mathematica 9似乎在这方面带来了显著的改进。@Rolf我刚刚用一个370 MB的mx文件进行了测试,它在不到一秒钟的时间内导入。我做了
rr=RandomReal[1,{100100,50}];DumpSave[“rr.mx”,rr];计时[获取[“rr.mx”];]
。我想知道为什么我们的经历不同。你在读什么样的数据?我的版本之所以快是因为它只有一个大的压缩数组吗?@Szabolcs是的,我有一个不同长度的压缩数组列表,而该列表本身无法压缩。这不是交换问题。问题是,我的数据超过了RAM的容量,因此我必须按顺序读取部分数据,而且这需要多次执行,因此,如果在这样一个MX文件中读取数据需要半分钟,这是显而易见的。事情确实可行,它只需要超过一天的CPU时间(有一个外部优化循环),所以我在考虑如何加快速度。我能用LibraryLink代码读入一大块数据,然后通过命令将其交换到磁盘上吗?现在我需要多次获取/清除同一个MX文件,基本上我想加快速度。我从来没有这样做过,所以我有点谨慎,但我认为这应该是可能的。在用C编写代码之前,我会确保文件读取是瓶颈,也许优化也可以调整。@ruebenko感谢分享这是可能的!我不知道我们可以编写自定义导入程序。您是否尝试过我的
dynamicPartition
(或者只是toolbag post中的核心
dynP
)功能?我认为应该比你的提议快一点。如果是的话,你会提供一个链接吗?@Mr.Wizard我在这里只是想说明以平面格式存储数据并在内核中对其进行分区是可行的