【问题标题】:Big matrices in MATLABMATLAB 中的大矩阵
【发布时间】:2018-11-15 15:46:58
【问题描述】:

按照我在this post 中的上一个问题:

我正在尝试构建一个包含 N 列(最多数百万)的 128 行矩阵。该矩阵的唯一目的是按列计算所有 128 行的平均值或中位数,并将其保存为向量(与我的数据的列数相同)。

我的数据文件的大小变化很大,使用上一篇文章中的代码(见上文),我已经能够执行此操作而没有任何问题。但是,当然,如果我正在处理更大的数据集,我的内存就会用完。请记住,错误在于将 128 行连接成一个新矩阵。

编辑用于连接文件中数据的代码如下:

for k = TTs;   %TTs to plot
    cd (strcat('TT',num2str(k)));   %TT folder

        for w = 1:4;
            load(strcat('TT',num2str(k),'ch',num2str(w),'.mat'));
            allChs1(4*(k-1)+w,:) = data(1,:);   %concatenate into one matrix
        end

    cd ..
end

我考虑过平均 128 行(逐列)并连续保存该值,但这样做完全不成功...

知道如何实现这一点吗?而且,是否有更好的方法来逐列获取 128 行的平均值?

干杯, 爱子

【问题讨论】:

  • 显示您尝试过的代码,minimal reproducible example(仅使用一个小例子,我们可以想象一些更大的输入),并指出它为什么不起作用。
  • @Wolfie 谢谢,刚刚添加了数据文件拼接的代码
  • 你在预分配allChs1吗?使用您在此处显示的代码,每次添加行时都会重新分配它,这意味着您使用的内存比需要的多。
  • 几百万是多少?一个 128x10,000,000 的双精度矩阵需要少于 10 GB。你有多少可用内存?
  • @Cris Luengo 实际上我没有预先分配...矩阵的大小事先不知道,我还没有设法充分更改代码以逐步分配。关于矩阵的大小,它的范围在几十到几亿之间

标签: matlab for-loop signal-processing


【解决方案1】:

您可以增量计算平均值,这样您就只有一个数据集和内存中的平均值:

均值[n] = 值[n]/n + 均值[n-1](n-1)/n*

avg_vector=0; % It will be changed to a vector at first iteration
for k = TTs;   %TTs to plot
    folder=['TT',num2str(k)];   %TT folder

        for w = 1:4;
            file = ['TT' num2str(k) 'ch' num2str(w) '.mat'];
            count = 4*(k-1)+w;
            load(fullfile(folder,file));
            avg_vector = (1/count) * data(1,:) + ((count-1)/count) * avg_vector;
        end
end

如果列数不是很大(在这种情况下,某些精度可能会因舍入误差而丢失),这将给出平均值。内存中唯一的大向量是avg_vectordata

对于中位数,这更复杂,因为没有增量公式。您可能需要在 1:N 的某个子集上添加另一个循环并进行选择。

filename=@(k,w) fullfile(['TT',num2str(k)],['TT' num2str(k) 'ch' num2str(w) '.mat']);
load(filename(1,1));
N=size(data,2);
median_all = zeros(1,N);

stride = 1e6;

for nn=1:stride:N
    rng = nn:min(N,nn+stride-1);
    MAT=zeros(128,length(rng));
    for k=TTs
        for w=1:4
            load(filename(k,w));
            MAT(4*(k-1)+w,:)=data(1,rng);
        end
    end
    median_all(1,rng) = median(MAT,1);
    clear MAT
end

矩阵 MAT 中最多有 1.28 亿个值,所以如果 data 是 64 位类型(例如双精度),则大约 1GB。缺点是,必须多次读取文件。平衡从内存消耗转移到文件 I/O。

【讨论】:

  • 谢谢,我马上试试!
  • 我已经测试了您的平均解决方案,并且 avg_vector 实际上与循环中打开的最后一个文件相同。没有计算平均值。知道错误可能在哪里吗?
  • 公式中有错字。它应该是avg_vector = (1/count) * data(1,:) + ((count-1)/count) * avg_vector(1,:);。我会编辑答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
  • 2013-10-22
相关资源
最近更新 更多