Data structures 大型二维阵列数据的数据结构

Data structures 大型二维阵列数据的数据结构,data-structures,language-agnostic,Data Structures,Language Agnostic,我使用一个输出2D数据数组的模拟,其中每列是一个不同的模拟变量(大约50000个变量),每行是每个时间样本(不同,但通常是10000个或更多时间点) 这些数据需要以两种不同的方式访问:要么获取少量变量的整个时间序列,要么获取特定时间点的每个变量。换句话说,有时我需要从数据中读取列,有时我需要读取行 目前,模拟以行主顺序输出二进制格式。这使得获取特定时间内的每个变量变得很容易,但是读取单个变量的整个时间序列非常慢,因为数据分布在整个千兆字节大小的文件中 是否有某种数据结构可以帮助我?我知道我可以有

我使用一个输出2D数据数组的模拟,其中每列是一个不同的模拟变量(大约50000个变量),每行是每个时间样本(不同,但通常是10000个或更多时间点)

这些数据需要以两种不同的方式访问:要么获取少量变量的整个时间序列,要么获取特定时间点的每个变量。换句话说,有时我需要从数据中读取列,有时我需要读取行

目前,模拟以行主顺序输出二进制格式。这使得获取特定时间内的每个变量变得很容易,但是读取单个变量的整个时间序列非常慢,因为数据分布在整个千兆字节大小的文件中

是否有某种数据结构可以帮助我?我知道我可以有效地将文件的大小增加一倍,并以行主顺序和列主顺序存储数据,但是文件已经相当大了


这里还有一些其他的问题我已经看过了,但是没有一个问题能够解决这个特定的用例。

只是一个免责声明-我不建议在您的程序中实现这个数据结构。它在行访问上浪费的时间比在列访问上节省的时间多。然而,如果您不能增加内存大小,并且如果您绝对必须改进列访问(比如,为了达到某个阈值以防止在其他地方暂停),那么这似乎是您唯一的选择

您可以调整2D数组,使从行和从列读取的速度都比以前从列读取的速度快,但是从行读取的性能会受到很大的影响。这也意味着索引特定位置的速度会变慢,但缓存未命中可能会产生更大的影响

为简单起见,假设矩阵的大小为NxN,并且N是一个完美的正方形。现在,我们可以安排原始矩阵的第i行在每个
i+k*sqrt(N)
元素的1D矩阵上展开。第j列将以
sqrt(N)
批出现在这些行之间(和相交)的拉伸中。所以类似于
floor(index/sqrt(N))*N+index mod sqrt(N)

这样做的目的是每N个元素,您现在就有相应行和列的sqrt(N)元素,而不是N个行元素,而是只有1个列元素。当您拉入缓存线时,您现在将拥有每个元素中的几个元素(至少提供一些缓存命中),而不管您是在遍历行还是列,而不是冒着“全部或全部”的风险。这是否是一个好的权衡取决于您需要改善最坏情况下的性能的程度,以及您对最佳情况下的性能的关注程度


要将现有二维数组转换为这种形式,可以获取构成矩阵下半部分的行,并将它们的列与其各自的上半部分行交错。然后取这个拉长矩阵的右半部分,将其行与左半部分的行交错。重复
sqrt(N)
次。请注意,这将非常缓慢-我并不是建议您使用它来转换数据库,我只是提供它作为理解数据结构的另一种方法。要转换数据库,我需要计算出公式,然后逐个移动每个元素。

根据您告诉我们的内容,我假设您的典型数据文件大约为4GB。考虑到当前的磁盘存储成本,这真的太多了吗?哎呀,现在16GB内存的笔记本电脑没什么特别的,你可以在内存中保存两次数据!我可以保证,没有人会提供一个聪明的数据结构,它将提供与当前以“正确”顺序读取文件时相同的行和列访问速度,以便按顺序从磁盘上传输数据。不幸的是,我们每天运行很多很多模拟。管理层不会批准遥测数据突然翻倍。我们的网络中不仅需要两倍的硬盘,而且还需要两倍的磁带备份。这并不重要,但为什么需要两倍的磁带备份呢?