2017-03-10 80 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 

>> 
相關問題