【问题标题】:Merging rows with the same date in a Matlab table在 Matlab 表中合并具有相同日期的行
【发布时间】:2017-03-11 06:04:27
【问题描述】:

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

column1 = datenum |第 2 列 = 国家 |列 3 = 值 1 |第 4 列 = 价值2

假设我加载了以下数据集(我手动添加了第一列以更好地向您显示行偏移量,不应将其视为数据集的一部分):

1   736561  'USA'       2752    251
2   736561  'USA'       184     53
3   736561  'USA'       40      0
4   736572  'England'   1       0
5   736573  'USA'       1       0
6   736575  'USA'       1       0
7   736576  'England'   1       0
8   736577  'USA'       2       0
9   736580  'USA'       1       1
10  736581  'USA'       1       0
11  736582  'USA'       1       0
12  736599  'USA'       1       0
13  736619  'USA'       5       0
14  736619  'France'    1       1
15  736683  'USA'       1       0

现在,我需要将具有相同日期的行合并在一起。如您所见,间隔 1:3 和 13:14 中的行就是这种情况。我必须遵循一些简单的标准来做到这一点:

  • 如果重复行中的国家始终相同,则最后一行仍应显示该国家,否则必须显示“多个”;
  • 最后一行的value1和value2必须是重复行的value1和value2之和。

按照这些标准,上例中的表格应该变成(再次强调,第一列是为了简化数据可视化,不应被代码考虑在内):

1   736561  'USA'       2976    304
2   736572  'England'   1       0
3   736573  'USA'       1       0
4   736575  'USA'       1       0
5   736576  'England'   1       0
6   736577  'USA'       2       0
7   736580  'USA'       1       1
8   736581  'USA'       1       0
9   736582  'USA'       1       0
10  736599  'USA'       1       0
11  736619  'Multiple'  6       1
12  736683  'USA'       1       0

【问题讨论】:

  • 我不知道我是否能够(很好地)解决这样一个问题,但我还是想问你一个问题:一个新的日期之后可以重复一个日期吗?出现了?换句话说,“相同的日期”总是重要的吗?
  • 是的,因为数据集按第一列(日期)升序排序。我想知道这种过滤是否可以在数据解析例程中以更简单的方式实现......

标签: matlab merge dataset unique


【解决方案1】:
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 

>> 

【讨论】:

    【解决方案2】:

    经过多次调试,我想出了这个解决方案:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多