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

5 visualizzazioni (ultimi 30 giorni)
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!

Risposta accettata

Peter Perkins
Peter Perkins il 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 Commenti
Bryan Ikeda
Bryan Ikeda il 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 il 8 Dic 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

Accedi per commentare.

Più risposte (1)

ICR
ICR il 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 Commento
Bryan Ikeda
Bryan Ikeda il 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!

Accedi per commentare.

Categorie

Scopri di più su Mathematics in Help Center e File Exchange

Prodotti


Release

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by