在Matlab表格中合并具有相同日期的行
我写这篇文章是希望有人能帮我解决一个需要很好解决的小问题。我有一个具有以下结构的表: column1=datenum | column2=country | column3=value1 | column4= 价值2 假设我加载了以下数据集(我手动添加了第一列以更好地显示行偏移量,不应将其视为数据集的一部分): 现在,我需要的是合并具有相同日期的行。如您所见,间隔为1:3和13:14的行就是这种情况。我必须遵循以下几个简单的标准:在Matlab表格中合并具有相同日期的行,matlab,merge,dataset,unique,Matlab,Merge,Dataset,Unique,我写这篇文章是希望有人能帮我解决一个需要很好解决的小问题。我有一个具有以下结构的表: column1=datenum | column2=country | column3=value1 | column4= 价值2 假设我加载了以下数据集(我手动添加了第一列以更好地显示行偏移量,不应将其视为数据集的一部分): 现在,我需要的是合并具有相同日期的行。如您所见,间隔为1:3和13:14的行就是这种情况。我必须遵循以下几个简单的标准: 如果重复行中的国家始终相同,则最后一行仍应显示该国家,否则必须
- 如果重复行中的国家始终相同,则最后一行仍应显示该国家,否则必须显示“多个”李>
- 最后一行的value1和value2必须是重复行的value1和value2之和
T =
datenum country val1 val2
_______ _________ ____ ____
736561 'USA' 2752 251
736561 'USA' 184 53
736561 'USA' 40 0
736572 'England' 1 0
736573 'USA' 1 0
736575 'USA' 1 0
736576 'England' 1 0
736577 'USA' 2 0
736580 'USA' 1 1
736581 'USA' 1 0
736582 'USA' 1 0
736599 'USA' 1 0
736619 'USA' 5 0
736619 'France' 1 1
736683 'USA' 1 0
S =
datenum country val1 val2
_______ __________ ____ ____
736561 'USA' 2976 304
736572 'England' 1 0
736573 'USA' 1 0
736575 'USA' 1 0
736576 'England' 1 0
736577 'USA' 2 0
736580 'USA' 1 1
736581 'USA' 1 0
736582 'USA' 1 0
736599 'USA' 1 0
736619 'Multiple' 6 1
736683 'USA' 1 0
>>
经过多次调试,我提出了以下解决方案:
data = cell2table(data,'VariableNames',{'Date','Country','Value1','Value2'});
[dat_uni,~,dat_idx] = unique(data.Date);
[cty_uni,~,cty_idx] = unique(data.Country);
cty_uni = [cty_uni; 'Multiple'];
cty_tmp = accumarray(dat_idx,cty_idx,[max(dat_idx) 1],@(x) {unique(x)});
mult = cellfun(@(x) length(x) > 1,cty_tmp);
cty_tmp{mult} = max(cty_idx) + 1;
cty_tmp = cat(1,cty_tmp{:});
data_new = table(dat_uni,cty_uni(cty_tmp),accumarray(dat_idx,data.Value1),accumarray(dat_idx,data.Value2));
我不知道我是否能(很好地)解决这样一个问题,但我还是想问你一个问题:一个新的日期出现后,一个日期能重复吗?换句话说,“相同的日期”总是相应的吗?是的,因为数据集是按第一列(日期)升序排序的。我想知道在数据解析例程中,这种过滤是否可以更容易地实现。。。
clear;clc;close all
datenum = [736561,736561,736561,736572,736573,736575,736576,736577,736580,736581,736582,736599,736619,736619,736683];
country = {'USA' ,'USA' ,'USA' ,'England','USA' ,'USA' ,'England','USA' ,'USA' ,'USA' ,'USA' ,'USA' ,'USA' ,'France' ,'USA' };
val1 = [2752, 184 , 40 , 1 , 1 , 1 , 1 , 2 , 1 , 1 , 1 , 1 , 5 , 1 , 1 ];
val2 = [251, 53, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0];
T = table(int32(datenum'),country',val1',val2','VariableNames',{'datenum' 'country' 'val1' 'val2'})
clearvars -except T
ind = find([1;diff(discretize(T.datenum,[unique(T.datenum);max(unique(T.datenum))+1]))]);
datenum = T.datenum(ind);
country = cell(length(ind),1);
[val1,val2] = deal(zeros(length(ind),1));
for ii = 1:length(ind)
if ii == length(ind)
grpind = ind(ii):ind(end);
else
grpind = ind(ii):(ind(ii+1)-1);
end
cc = T.country(grpind);
if length(unique(cc))~=1
cc = 'Multiple';
else
cc = cc{1};
end
country{ii} = cc;
val1(ii) = sum(T.val1(grpind));
val2(ii) = sum(T.val2(grpind));
end
S = table(int32(datenum),country,val1,val2,'VariableNames',{'datenum' 'country' 'val1' 'val2'})
T =
datenum country val1 val2
_______ _________ ____ ____
736561 'USA' 2752 251
736561 'USA' 184 53
736561 'USA' 40 0
736572 'England' 1 0
736573 'USA' 1 0
736575 'USA' 1 0
736576 'England' 1 0
736577 'USA' 2 0
736580 'USA' 1 1
736581 'USA' 1 0
736582 'USA' 1 0
736599 'USA' 1 0
736619 'USA' 5 0
736619 'France' 1 1
736683 'USA' 1 0
S =
datenum country val1 val2
_______ __________ ____ ____
736561 'USA' 2976 304
736572 'England' 1 0
736573 'USA' 1 0
736575 'USA' 1 0
736576 'England' 1 0
736577 'USA' 2 0
736580 'USA' 1 1
736581 'USA' 1 0
736582 'USA' 1 0
736599 'USA' 1 0
736619 'Multiple' 6 1
736683 'USA' 1 0
>>
data = cell2table(data,'VariableNames',{'Date','Country','Value1','Value2'});
[dat_uni,~,dat_idx] = unique(data.Date);
[cty_uni,~,cty_idx] = unique(data.Country);
cty_uni = [cty_uni; 'Multiple'];
cty_tmp = accumarray(dat_idx,cty_idx,[max(dat_idx) 1],@(x) {unique(x)});
mult = cellfun(@(x) length(x) > 1,cty_tmp);
cty_tmp{mult} = max(cty_idx) + 1;
cty_tmp = cat(1,cty_tmp{:});
data_new = table(dat_uni,cty_uni(cty_tmp),accumarray(dat_idx,data.Value1),accumarray(dat_idx,data.Value2));