我有一个矩阵A
,其中包含第一列user_id
,第二列year
,第三列month
,第四列day
A=[0 2010 10 19;
0 2010 10 19;
0 2010 10 18;
0 2010 10 18;
0 2010 10 17;
0 2010 10 17;
0 2010 9 20;
0 2010 9 19;
0 2010 9 19;
0 2010 9 19]
我想根据月和日划分这些数据。我怎么能在MATLAB中做到这一点?
答案 0 :(得分:4)
您可以使用unique
按月和日(第3列和第4列)对每一行进行分组,然后使用splitapply
对共享一个月/天的每组行执行操作。我们要执行的操作是简单地将它们放入单元格数组中:@(x){x}
。以下代码可以实现此目的。
% Assign each unique month/day combination an ID
[~, ~, inds] = unique(A(:,[3 4]), 'rows');
% Divide up the rows based upon this ID
groups = splitapply(@(x){x}, A, inds);
celldisp(groups)
groups{1} =
0 2010 9 19
0 2010 9 19
0 2010 9 19
groups{2} =
0 2010 9 20
groups{3} =
0 2010 10 17
0 2010 10 17
groups{4} =
0 2010 10 18
0 2010 10 18
groups{5} =
0 2010 10 19
0 2010 10 19
话虽这么说,你可以在没有实际将数据分成不同部分的情况下进行分析。由于MATLAB针对矩阵运算进行了优化,因此这可能会更高效。
有关splitapply
的更多信息,并对您的数据进行分组here
答案 1 :(得分:3)
如果你有版本R2015b,函数splitapply
是一个很好的函数(实际上我从来没有听说过这个函数)。如果您没有这项功能,那么拨打accumarray
可能是谨慎的。在使用唯一ID分配每个唯一月份和日期时使用相同的逻辑,您可以使用accumarray
查找共享相同ID的行位置,然后通过使用这些行位置切片并返回来访问矩阵并返回元素的单元格数组中每个ID的矩阵子集,非常类似于splitapply
。
这样的事情可行:
% Assign each unique month/day combination an ID
% From Suever
[~,~,inds] = unique(A(:,[3 4]), 'rows');
% Divide up the rows based upon this ID
groups = accumarray(inds, (1:size(A,1)).', [], @(x) {A(x,:)});
我们得到:
>> format compact
>> celldisp(groups)
groups{1} =
0 2010 9 19
0 2010 9 19
0 2010 9 19
groups{2} =
0 2010 9 20
groups{3} =
0 2010 10 17
0 2010 10 17
groups{4} =
0 2010 10 18
0 2010 10 18
groups{5} =
0 2010 10 19
0 2010 10 19
答案 2 :(得分:3)
这是另一种方法:
A
行进行排序; 代码:
key = [3 4]; % columns used as key for splitting
As = sortrows(A, [3 4]); % sort based on that (step 1)
chunks = diff([0; find(any(diff(As(:, [3 4]), [], 1), 2)); size(A,1)]); % sizes (step 2)
result = mat2cell(As, chunks, size(A,2)); % split with those sizes (step 3)
使用您的示例数据
A = [0 2010 10 19;
0 2010 10 19;
0 2010 10 18;
0 2010 10 18;
0 2010 10 17;
0 2010 10 17;
0 2010 9 20;
0 2010 9 19;
0 2010 9 19;
0 2010 9 19];
这给出了
>> celldisp(result)
result{1} =
0 2010 9 19
0 2010 9 19
0 2010 9 19
result{2} =
0 2010 9 20
result{3} =
0 2010 10 17
0 2010 10 17
result{4} =
0 2010 10 18
0 2010 10 18
result{5} =
0 2010 10 19
0 2010 10 19