在Matlab表格中合并具有相同日期的行

在Matlab表格中合并具有相同日期的行,matlab,merge,dataset,unique,Matlab,Merge,Dataset,Unique,我写这篇文章是希望有人能帮我解决一个需要很好解决的小问题。我有一个具有以下结构的表: column1=datenum | column2=country | column3=value1 | column4= 价值2 假设我加载了以下数据集(我手动添加了第一列以更好地显示行偏移量,不应将其视为数据集的一部分): 现在,我需要的是合并具有相同日期的行。如您所见,间隔为1:3和13:14的行就是这种情况。我必须遵循以下几个简单的标准: 如果重复行中的国家始终相同,则最后一行仍应显示该国家,否则必须

我写这篇文章是希望有人能帮我解决一个需要很好解决的小问题。我有一个具有以下结构的表:

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));