2017-10-11 29 views
3

我正在尋找方法,內置函數,最佳實踐...將新數據追加到矩陣 - 當行和列不相同時 - 在Matlab中添加新數據的高效方法(使用示例代碼)

我處理的結構爲數據如下:

A.values: Ta x Ma matrix of values 
A.dates: Ta x 1 vector of datenum 
A.id:  1 x Ma cell array of ids 

現在面臨的挑戰是如何處理,我加載和想追加到一個新的矩陣新的(可能重疊的)數據BC

當有新的數據進來,它可以擴大水平和垂直方向由於:

  • 新的ID
  • 新日期

它也可以有以前min(A.dates)開始日期max(A.dates)之間min(A.dates)max(A.dates)。 ID可以全部在B中獨一無二(全新),或者一些可以重疊。

下面是一個例子:

A.values = [2.1 2.4 2.5 2.6; ... 
      4.1 4.4 4.5 4.6; ... 
      6.1 6.4 6.5 6.6]; 
A.dates = [730002; ... 
      730004; ... 
      730006]; 
A.id  = {'x1', 'x4', 'x5', 'x6'}; 

現在,新的數據進來:

B.values = [1.2 1.9 1.5 1.6 1.7; ... 
      3.2 3.9 3.5 3.6 3.7; ... 
      7.2 7.9 7.5 7.6 7.7; ... 
      8.2 8.9 8.5 8.6 8.7]; 
B.dates = [730001; ... 
      730003; ... 
      730007; ... 
      730008]; 
B.id  = {'x2', 'x9', 'x5', 'x6', 'x7'}; 

我們現在怎麼辦高效,快速地構建新的結構C

C.values = [NaN 1.2 NaN 1.5 1.6 1.7 1.9; ... 
      2.1 NaN 2.4 2.5 2.6 NaN NaN; ... 
      NaN 3.2 NaN 3.5 3.6 3.7 3.9; ... 
      4.1 NaN 4.4 4.5 4.6 NaN NaN; ... 
      6.1 NaN 6.4 6.5 6.6 NaN NaN; ... 
      NaN 7.2 NaN 7.5 7.6 7.7 7.9; ... 
      NaN 8.2 NaN 8.5 8.6 8.7 8.9]; 
C.dates = [730001; ... 
      730002; ... 
      730003; ... 
      730004; ... 
      730006; ... 
      730007; ... 
      730008]; 
C.id  = {'x1', 'x2', 'x4', 'x5', 'x6', 'x7', 'x9'}; 

更新與時間表

繼意見,我試着用timetable實現這一目標如下:

function dfmerged = in_mergeCache(dfA, dfB) 

dtA = datenum2datetime(dfA.dates); % function datenum2datetime can be found here: https://stackoverflow.com/a/46685634/4262057 
dtB = datenum2datetime(dfB.dates); 

TTa = array2timetable(dfA.values, 'RowTimes', dtA, 'VariableNames', dfA.id); 
TTb = array2timetable(dfB.values, 'RowTimes', dtB, 'VariableNames', dfB.id); 

TTs = synchronize(TTa,TTb); 

dfmerged.id  = TTs.Properties.VariableNames; 
dfmerged.values = table2array(TTs); 
dfmerged.dates = datenum(TTs.Time); %to convert datenum 

end 

問題:但是,這給了我一個很大的時間表,其中行確實同步的行,但只是重複的列(9列)。我怎樣才能同步列?

C = 

    struct with fields: 

     id: {'x1' 'x4' 'x5_TTa' 'x6_TTa' 'x2' 'x9' 'x5_TTb' 'x6_TTb' 'x7'} 
    values: [7×9 double] 
    dates: [7×1 double] 
+0

哪個版本的MATLAB您使用的是?從2016b開始,你可以使用'timetable'對象和'synchronize'這樣的東西 – Wolfie

+0

啊發現了:)這樣的例子在上面會怎麼樣呢?我必須在時間表中改變一切嗎?這不會花費很多時間嗎? – JohnAndrews

+0

您可以將數據存儲在表格中,無需更改代碼,因爲表格變量可以使用點符號與結構相同的方式進行訪問,但事情可能會更簡單;鑑於您基本上擁有標題和行數據的表格結構 – Wolfie

回答

1

下面是一個解決方案使用unique和索引:

%combine the data and take unique value of them + their index 
[C.id,~,date_i] = unique([A.dates(:);B.dates(:)]); 
[C.dates,~,id_i] = unique([A.id B.id]); 

C.values = nan(numel(C.dates),numel(C.id)); 
%use matrix indexing to fill the sub-materices corresponding to elements of A and B 
C.values(date_i(1:numel(A.dates)),id_i(1:numel(A.id)))=A.values; 
C.values(date_i(numel(A.dates)+1:end),id_i(numel(A.id)+1:end))=B.values; 
+0

AB不會工作,因爲它們可能有不同的行數。 A和B的行數和列數是不同的。 – JohnAndrews

+0

數值範圍是從「1.1」到「9.9」嗎? – rahnema1

+0

不,他們總是改變。請參閱示例A和B.預先未知行數。列數也可能不同。所以我們需要同時進行水平和垂直同步。 – JohnAndrews

相關問題