在MATLAB中按列值拆分数值矩阵

时间:2013-09-07 22:18:17

标签: matlab matrix

我在50572x4 doubles的MATLAB中有一个矩阵。最后一列的格式为datenum个日期,值从7.3025e+05增加到7.3139e+05。问题是:

如何将此矩阵拆分为子矩阵,每个子矩阵的间隔时间为30天?

如果我不够清楚......第4列中的第一个元素与第4列中的最后一个元素之间的差异是7.3139e5 − 7.3025e5 = 1.1376e31137.6。我想把它分成30天的段,然后得到一堆矩阵,第4列的范围是30。我不太确定如何做到这一点......我对MATLAB很新,但我正在使用的数据集只有这种表示,需要采取这样的行动。

2 个答案:

答案 0 :(得分:0)

嗯,您只需找到边缘时间和它们之间的矩阵索引。因此,如果你的数字是datenum格式,一个单位与一天相同,这意味着我们可以从30和30单位跳到我们尽可能接近最后,如下:

startTime = originalMatrix(1,4);
endTime = originalMatrix(end,4);

edgeTimes = startTime:30:endTime;

% And then loop though the edges checking for samples that complete a cycle:

nEdges = numel(edgeTimes);
totalMeasures = size(originalMatrix,1);

subMatrixes = cell(1,nEdges);

prevEdgeIdx = 0;

for curEdgeIdx = 1:nEdges
  nearIdx=getNearestIdx(originalMatrix(:,4),edgeTimes(curEdgeIdx));
  if originalMatrix(nearIdx,4)>edgeTimes(curEdgeIdx)
    nearIdx = nearIdx-1;
  end
  if nearIdx>0 && nearIdx<=totalMeasures
    subMatrix{curEdgeIdx} = originalMatrix(prevEdgeIdx+1:curEdgeIdx,:);
    prevEdgeIdx=curEdgeIdx;
  else
    error('For some reason the edge was not inbound.');
  end
end

% Now we check for the remaining days after the edges which does not complete a 30 day cycle:

if curEdgeIdx<totalMeasures
  subMatrix{end+1} = originalMatrix(curEdgeIdx+1:end,:);
end

我们讨论了getNearestIdx函数here,它会在不检查所有可能点的情况下为您提供距输入值最近的点。

function vIdx = getNearestIdx(values,point)


if isempty(values) || ~numel(values)
  vIdx = [];
  return
end


vIdx = 1+round((point-values(1))*(numel(values)-1)...
  /(values(end)-values(1)));
  if vIdx < 1, vIdx = []; end
  if vIdx > numel(values), vIdx = []; end
end

注意:这是伪代码,可能包含错误。请尝试将其调整为您的问题。

答案 1 :(得分:0)

请注意,datenum时间戳之间的单位间隔代表1天,因此您的数据实际上涵盖了1137.6天的时间段。直接的方法是将每个时间戳与边缘进行比较,以确定它属于哪个30天的间隔:

t = A(:, end) - min(A:, end);            %// Normalize timestamps to start from 0
idx = sum(bsxfun(@lt, t, 30:30:max(t))); %// Starting indices of intervals
rows = diff([0, idx, numel(t)]);         %// Number of rows in each interval

其中A是您的数据矩阵,其中假设最后一列包含时间戳。 rows存储相应30天间隔的行数。最后,您可以使用单元格数组来拆分原始数据矩阵:

C = mat2cell(A, rows, size(A, 2));       %// Split matrix into intervals
C = C(~cellfun('isempty', C));           %// Remove empty matrices

希望它有所帮助!