2017-03-10 87 views
2

我正在写这篇文章,希望有人能帮助我解决一个需要良好解决方案的小问题。我有一张具有以下结构的表格:在Matlab表中合并具有相同日期的行

column1 = datenum | column2 = country | column3 = value1 | column4 = 值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的行就是这种情况。我必须这样做以下几个简单的标准:

  • 如果在重复行的国家是永远不变的,最后一行还是应该表现出该国,否则就必须表现出“多”;
  • 最终行的值1和值2必须是重复行的值1和值2之和。

继这些标准,在上述例子中的表应该成为(再次,第一列是在这里为了简化数据可视化和不应该由代码考虑在内):

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 
+1

我不知道我是否能够解决(很好)这样的问题,但我想问你一个问题,但是:在一个新的日期出现后可以重复一个日期吗?换句话说,“相同的日期”总是相应的吗? – UJIN

+0

是的,因为数据集按第一列(日期)按升序排序。我想知道这种过滤可以在数据解析例程中以更简单的方式实现...... –

回答

1

许多调试会话后,我想出了这个解决方案:

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

>> 
相关问题