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

조회 수: 5 (최근 30일)
Bryan Ikeda
Bryan Ikeda 2020년 11월 14일
댓글: Peter Perkins 2020년 12월 8일
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!

채택된 답변

Peter Perkins
Peter Perkins 2020년 11월 19일
"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
Bryan Ikeda
Bryan Ikeda 2020년 11월 20일
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 2020년 12월 8일
Bryan, you can store the timestamps as datetimes, and then convert to "fractional days" in the calculation. Something like
seconds(timeofday(tt12.Time)) / 86400

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

ICR
ICR 2020년 11월 14일
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
Bryan Ikeda
Bryan Ikeda 2020년 11월 15일
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!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Mathematics에 대해 자세히 알아보기

태그

제품


릴리스

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by