2017-10-11 3 views
3

Je recherche des méthodes, des fonctions intégrées, de bonnes pratiques ... pour ajouter de nouvelles données à une matrice - lorsque les lignes et les colonnes ne sont pas les mêmesMoyens efficaces pour ajouter de nouvelles données dans Matlab (avec code exemple)

les données je traite est structuré comme suit:

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 

maintenant, le défi est de savoir comment faire face aux nouveaux (chevauchement potentiellement) des données B que je charge et voudrais ajouter à une nouvelle matrice C:

Lorsque de nouvelles données arrive, il peut développer à la fois horizontalement et verticalement en raison de:

  • nouveaux ids
  • nouvelles dates

Il peut aussi avoir des dates qui commencent avantmin(A.dates) ou aprèsmax(A.dates) ou entre et max(A.dates). Les identifiants peuvent être tous uniques en B (tous nouveaux) ou certains peuvent se chevaucher.

Voici un exemple:

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'}; 

maintenant de nouvelles données est disponible en:

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'}; 

Comment construire maintenant efficacement et rapidement la nouvelle struct 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'}; 

Mise à jour avec le calendrier

Suite aux commentaires, j'ai essayé d'y parvenir avec timetable comme suit:

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 

Problème: Cependant, cela m'a donné un grand horaire, où les lignes sont effectivement synchronisées, mais les colonnes où il suffit de dupliquer (9 colonnes). Comment puis-je également synchroniser les colonnes?

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

Quelle version de Matlab utilisez-vous? A partir de 2016b vous pouvez utiliser les objets 'schedule' et' synchroniser' pour ce genre de choses – Wolfie

+0

Ah l'ai trouvé :) Comment un tel exemple se jouerait-il dans ce qui précède? Je dois tout transformer en horaires? Ça ne va pas prendre beaucoup de temps? – JohnAndrews

+0

Vous pouvez stocker vos données dans des tables en premier lieu, vous n'aurez pas besoin de changer votre code autant que les variables de table peuvent être accessibles avec la notation par points les mêmes que les structures, mais les choses pourraient être un peu plus facile; étant donné que vous avez essentiellement une structure de table des en-têtes et des données de ligne de toute façon – Wolfie

Répondre

1

Voici une solution en utilisant unique et indexation:

%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 ne va pas fonctionner, car ils pourraient avoir un nombre différent de lignes. Le nombre de lignes et de colonnes est différent entre A et B. – JohnAndrews

+0

Les valeurs vont-elles de '1.1'' '9.9'? – rahnema1

+0

Non, ils changent toujours. Voir l'exemple A vs B. Le nombre de lignes n'est pas connu à l'avance. Le nombre de colonnes peut également différer. Nous devons donc synchroniser horizontalement et verticalement. – JohnAndrews