Effacer les filtres
Effacer les filtres

Matching the size of two matrices based on values of a column

6 vues (au cours des 30 derniers jours)
Bryan Ikeda
Bryan Ikeda le 14 Nov 2020
Commenté : Peter Perkins le 8 Déc 2020
I'm trying to make two matrices have the same dimensions, by matching up the values in the third column. The third column contains time in a day in decimal form. One of the matrix only runs for a certain time, and I want the 2nd matrix to match that length and line up the times. I'm currently using the code: where B is the matrix with the 24hr time frame and A has a smaller timeframe.
function [refined] = samesized( A, B)
[row,~] = size(A);
[rows,cols] = size(B);
re = zeros(rows,cols);
i = 1;
j = 1;
while i < row
while j < rows
if A(i,3) == B(j,3)
refined(i,3) = B(j,3);
refined(i,2) = B(j,2);
refined(i,1) = B(j,1);
end
j = j+1;
end
j = 1;
i = i+1;
end
refined( ~any(refined,2), : ) = [];
end
However, it sometimes skips values in the output and actually makes the returned matrix smaller, even though the values in column matched. I was wondering if anyone could help me figure out how to fix this, or know of a better way to do it.
Thanks!

Réponse acceptée

Peter Perkins
Peter Perkins le 19 Nov 2020
"contains time in a day in decimal form": That would be your problem. Use timetables with datetimes (or maybe durations?), and use the [inner|outer]join function.
>> tt1 = timetable(rand(10,1),'RowTimes',datetime(2020,11,1:10)+hours(1:10));
>> tt2 = timetable(rand(5,1),'RowTimes',datetime(2020,11,1:2:10)+hours(1:2:10));
>> tt12 = innerjoin(tt1,tt2,'Key','Time')
tt12 =
5×2 timetable
Time Var1_tt1 Var1_tt2
____________________ ________ ________
01-Nov-2020 01:00:00 0.13755 0.29541
03-Nov-2020 03:00:00 0.6501 0.99014
05-Nov-2020 05:00:00 0.32355 0.16225
07-Nov-2020 07:00:00 0.68174 0.44102
09-Nov-2020 09:00:00 0.54227 0.55718
  2 commentaires
Bryan Ikeda
Bryan Ikeda le 20 Nov 2020
Hmm, okay thanks. I'll need to look for a workaround because the date comes in decimal form due to it being used for a calculation for solar position, and the smaller matrix is coming from an xcel data sheet.
Peter Perkins
Peter Perkins le 8 Déc 2020
Bryan, you can store the timestamps as datetimes, and then convert to "fractional days" in the calculation. Something like
seconds(timeofday(tt12.Time)) / 86400

Connectez-vous pour commenter.

Plus de réponses (1)

ICR
ICR le 14 Nov 2020
Hi,
This should work.
% Generate random integers
B = randi(24,[24 3]);
B(:,3) = 24:-1:1; % Replace these two your data
A = randi(15,[15 3]);
A(:,3) = randperm(15,15)'; % Replace these two your data
[r1,c1] = size(A)
outputMat = zeros(r1,c1); % Initialise
for i =1:1:r1
[row,~] = find(B(:,3) == A(i,3))
outputMat(i,:) = B(row,:);
end
  1 commentaire
Bryan Ikeda
Bryan Ikeda le 15 Nov 2020
Hmm, the test example you gave worked, but when I put the actual numbers in it gave the following error:
Unable to perform assignment because the size of the left side is 1-by-3 and the size of the right side is
0-by-3.
Error in samesized3 (line 6)
outputMat(i,:) = B(row,:);
I should also mention that the hours in column 3 are not all integers, they are divided into 5 minute intervals (ie: 12:05 pm is 12.083), I'm wondering if that is causing some of the problems.
Thanks!

Connectez-vous pour commenter.

Catégories

En savoir plus sur Mathematics dans Help Center et File Exchange

Produits


Version

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by