Hi everyone, i have a question about a for loop. i got a 2-column data, the first column is date data(e.g. 194501011000 means year, month, data and time 10:00), the second column is rainfall depth. What i want to do is select all the data that happend in the same year (like 1945) and then output a new table that only contains rainfall depth for year 1945. The code is as below:
function [B]=Seperate_DATA(data,year)
a=data(:,3)
b=num2str(a)
for i=1:size(data)
if b(i,1:4)==num2str(year)
A(i)=data(i,4)
end
B=reshape(A,[],1)
end
end
Firstly i transfered the time column to string and then selected the first four characters so that it can be compared to the if conditions. data(i,4) means the orignal data that contains the rainfall depth. It works when i put the year 1945, but when i put 1946, it will give me the 1945 results and 1946 results together, with data in 1945 all 0 values. Is there anyone who can tell me where is the problem is? Thank you. I am just a beginer...

 Akzeptierte Antwort

Walter Roberson
Walter Roberson am 27 Okt. 2017

1 Stimme

Generalized to permit multiple years:
B = A( ismember(floor(data(:,1) ./ 10^8), year), :)

11 Kommentare

Yu Zhang
Yu Zhang am 28 Okt. 2017
thank you for your answer. but sorry sir, could you explian a little more?
Walter Roberson
Walter Roberson am 29 Okt. 2017
floor(data(:,1) ./ 10^8 gets rid of the last 8 digits, leaving only the year. Then you ismember() that list of years of the data against the list of years you are interested in. The ismember() returns true for each of the source years that matches one of the target years. Then that list of true/false values is used as a logical index into the row index of A, so selecting all of the rows of A that have a matching year.
Yu Zhang
Yu Zhang am 3 Nov. 2017
Bearbeitet: Walter Roberson am 3 Nov. 2017
thank you so much! could you tell me how to make this a loop? e.g., i have year from 1945 to 2013, so i want 68 seperated tables that can be done in one time. i made a for loop like this:
for year=1945:1946
E(year) = B( ismember(floor(B(:,1)./ 10^8), year), :)
end
but it told me that:
In an assignment A(:) = B, the number of elements in A and B must be the same.
Error in Seperate_DATA (line 3)
E(year) = B( ismember(floor(B(:,1)./ 10^8), year), :)
for year=1945:1946
E{year-1944} = B( ismember(floor(B(:,1)./ 10^8), year), :)
end
Yu Zhang
Yu Zhang am 3 Nov. 2017
thank you but it shows: Cell contents assignment to a non-cell array object.
Error in Seperate_DATA (line 3) E{year-1944} = B( ismember(floor(B(:,1)./ 10^8), year), :)
Walter Roberson
Walter Roberson am 3 Nov. 2017
You have an old E array hanging around.
Yu Zhang
Yu Zhang am 7 Nov. 2017
thank you sir! you helped me a lot. could you help me a little more...so now i have E as a list,is that correct? how can i operate in a list like operating a table? e.g., i want to find each year's maximum 6 consecutive value. (each year has 8928 rows, i want to find the maximum of 6 consecutive rows for a particular column) Thank you!
E is a cell array consisting of numeric arrays -- the code preserves the data information in the first column just in case it was needed. For example if you wanted to know the dates of the 6 consecutive entries then the dates are there in the first column.
t1 = cellfun(@(M) [0; cumsum(double(M(:,2)))], E, 'uniform', 0);
t2 = cellfun(@(M) M(7:end)-M(1:end-6), t1, 'uniform', 0);
[max6val, max6idx] = cellfun(@max, t2, 'uniform', 0);
max6info = cellfun(@(M, idx6) M(idx6:idx6+5,:), E, max6idx, 'Uniform', 0);
Now max6info is a cell array with one entry per E member, containing the 6 consecutive data lines that give the maximum total rainfall over the 6 days.
Yu Zhang
Yu Zhang am 7 Nov. 2017
OH my god, that's magic to me...Thanks a lot! i am so new in matlab, could you tell me how do i get the data in the arrays? e.g., i would like to sum the 6 consecutive data in each cell of the array, and then output a table with results of each year's maximum.
The totals are already in the cell array max6val.
If you want the start dates rather than the dates for all 6 items, then
shortinfo = cellfun(@(M, tot6, idx6) [M(idx6,1), tot6], E, max6val, max6idx, 'Uniform', 0);
This has the start date in the first column and the 6 day total in the second column.
Yu Zhang
Yu Zhang am 7 Nov. 2017
thanks! i forgot to check other arrays.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by