【问题标题】:Is it better to store timeseries data in Matlab across rows or columns? [closed]在 Matlab 中跨行或跨列存储时间序列数据更好吗? [关闭]
【发布时间】:2016-05-31 17:19:37
【问题描述】:

是否有一种建模约定可以在每个时间步将一些不断变化的数据集存储在行或列中?例如,如果我有一些包含 10 个空间点的数据集,每个时间步的值 x t 并且我有 20 个时间步,我应该将 x 的值存储在行 t 的所有列中(使20x10 矩阵)还是应该将 x 的值存储在 t 列的所有行中(制作 10x20 矩阵)?

我承认这并没有从根本上改变任何事情,但我想保持一致,并认为我可能会看到约定是什么,或者根本没有约定。这两种方法的优缺点是什么。

【问题讨论】:

  • 这完全是个人喜好。一些 MATLAB 内部结构(例如 plot)假设每一列都是时间序列,但这绝不是标准的。
  • 我做了很多 M&S,标准用法是将时间放在第一列,并在附加列中列出数据点。这是个人偏好,但如果您正在生成许多其他人将要使用的数据,那么考虑标准用法是明智的。但是,到目前为止,最重要的考虑是清楚地标记所有内容。

标签: matlab data-modeling


【解决方案1】:

假设您关心的是性能,那么这取决于您访问数据的方式。连续访问内存中连续的元素会更快。 Matlab stores matrices in column-major order,例如如果您需要在时间维度上进行迭代,那么迭代特定列的行会比迭代特定行的列更有效。

在 Mathworks 网站上有一篇关于这个主题的好文章 - Programming Patterns: Maximizing Code Performance by Optimizing Memory Access

您的代码在遍历时实现了最大的缓存效率 单调增加的内存位置。因为 MATLAB 存储 单调增加的内存位置中的矩阵列, 按列处理数据可实现最大的缓存效率。

考虑这个例子。首先,尝试从不同的列(会分散在不同的内存块中)依次访问数据:

N = 2e4;
X = randn(N,N);
tic;
for i = 1:N
   for j = 1:N
       if X(i,j) >= 0
           X(i,j) = X(i,j) + 1;
       end
   end
end
toc;

>> Elapsed time is 29.200216 seconds.

然后反过来——首先遍历列,而不是行:

N = 2e4;
X = randn(N,N);
tic;
for j = 1:N
   for i = 1:N
       if X(i,j) >= 0
           X(i,j) = X(i,j) + 1;
       end
   end
end
toc;

>> Elapsed time is 8.084906 seconds.

惊人的 3.6 倍 加速。确切的比例可能会根据 Matlab 版本和您的 PC 明显不同,但模式非常明确。

出于同样的原因,从矩阵中提取列向量比提取行向量要快。一些内置函数也可以稍微更快地处理列,但您需要分别分析每种情况。

所以这实际上取决于您的实际代码以及您如何处理时间序列。您可以尝试这两个选项并对其进行分析,以查看哪种变体可以带来更好的性能。但一般来说,在处理时间序列数据时,您可以使用以下经验法则:

  • 如果您倾向于随时间迭代(通常是这种情况),请将时间序列存储在单独的列中。
  • 如果您倾向于以空间/横截面方式进行迭代,请将时间序列存储在单独的行中。

【讨论】:

    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 2016-04-17
    • 2014-08-12
    • 2021-03-31
    • 2011-03-17
    • 2012-05-26
    • 1970-01-01
    • 2016-10-31
    相关资源
    最近更新 更多