SOLVED: Summing values together until certain value is reached - then repeat - and plot

조회 수: 29 (최근 30일)
Let's get right into it:
I have yearly data for water level increase in my water tank. I need to find out that on which days the water level reaches tank capacity (lets say 500 liters), then plotting these days on the same graph as the 'water per day'. When the maximum capacity is reached (= tank is emptied), the "countdown" should then start again, and so on.
Experimenting with cumsum has gotten me nowhere and I have not managed to create a sufficient loop to do this.
% Time of year % Water per day [liters]
'01-Jan-2018 00:00:00' 50.2106332550196
'02-Jan-2018 00:00:00' 69.1231162561486
'03-Jan-2018 00:00:00' 39.2133461192996
'04-Jan-2018 00:00:00' 35.1911633369915
'05-Jan-2018 00:00:00' 70.7909634228800
'06-Jan-2018 00:00:00' 45.2770948623210
'07-Jan-2018 00:00:00' 103.742125124495
'08-Jan-2018 00:00:00' 104.090498552586
'09-Jan-2018 00:00:00' 49.9451044989908
'10-Jan-2018 00:00:00' 9.75987421081660
'11-Jan-2018 00:00:00' 8.65371484802794
'12-Jan-2018 00:00:00' 2.47031260215833
'13-Jan-2018 00:00:00' 28.3093648636441
'14-Jan-2018 00:00:00' 113.381792987146
I've tried scrolling through the forums and stackexchange but no luck so far. I found the following answer to a similar problem, but the thread was 6 years old and I did not get it to work in MATLAB 2019b (with the $ and everything).
df$difference_sum <- c(0, head(cumsum(df$difference), -1))
# get length of 0's (first keep value gives the actual length)
len <- sum(df$difference_sum %/% 500 == 0)
df$keep <- (seq_len(nrow(df))-1) %/% len
df <- transform(df, difference_sum = ave(difference, keep,
FUN=function(x) c(0, head(cumsum(x), -1))))
I also tried to following loop, to no avail.
A= H2O_perday;
sum1=0;
k=1;
s = [];
while sum1 < 500
s =sum1;
sum1=sum1+A(k);
k=k+1;
end
disp(s);
disp(k-1);
Does anyone here have experience with a similar issue that could help me or show me some tips on how to proceed in this?

채택된 답변

dpb
dpb 2020년 1월 28일
OK, a working script...I set the setpoint to 250 so would have more than one condition satisfied for testing...
tt.Level=zeros(height(tt),1);
C = 250;
tt.Level=cumsum(tt.Fill);
i1 = 1;
i2 = find(tt.Level>=C,1);
while i2 <= height(tt)
i1=i2+1;
%tt.Level(i1:end) = tt.Level(i1:end) - tt.Level(i1);
tt.Level(i1:end)=cumsum(tt.Fill(i1:end));
i2=find(cumsum(tt.Fill(i1:end))>=C,1) + i1-1;
if isempty(i2), break, end
end
produced:
>> tt
tt =
14×2 timetable
Time Fill Level
___________ ______ ______
01-Jan-2018 50.21 50.21
02-Jan-2018 69.12 119.33
03-Jan-2018 39.21 158.55
04-Jan-2018 35.19 193.74
05-Jan-2018 70.79 264.53
06-Jan-2018 45.28 45.28
07-Jan-2018 103.74 149.02
08-Jan-2018 104.09 253.11
09-Jan-2018 49.95 49.95
10-Jan-2018 9.76 59.70
11-Jan-2018 8.65 68.36
12-Jan-2018 2.47 70.83
13-Jan-2018 28.31 99.14
14-Jan-2018 113.38 212.52
>>
  댓글 수: 1
Tarmo Tukiainen
Tarmo Tukiainen 2020년 1월 29일
Perfect! It works like a charm also with the hourly data I have stored. Thank you for all your help and I wish you a good rest of the week!

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

추가 답변 (1개)

dpb
dpb 2020년 1월 24일
Not fully coded, but the idea should work to build loop...
t=readtable('tarmo.dat','HeaderLines',1);
t.Var1=strrep(t.Var1,'''',''); % remove extra ' in the date strings
t.Var1=datetime(t.Var1); % convert to date
t=timetable(t.Var3,'rowtimes',t.Var1); % make into time table
t.Properties.VariableNames={'DailyFill (l)'};
C=500; % Capacity level
i1=1;
i2=find(cumsum(t.("DailyFill (l)"))>=C,1); % First location exceed capacity
while i2<=height(t) % iterate
i1=i2+1; % next start
t.Level(i1:end)=t.Level(i1:end)-tt.Level(i1); % reset
t.(Level,i1:end)=cumsum(t.("DailyFill (l)")(i1:end)); % new cumulative flow (fill)
i2=find(cumsum(t.("DailyFill (l)")(i:end)>=C,1)+i1; % First location exceed capacity beginning next
end
WARNING: Air code, only minimally tested for first/second cases sequentially at command line; not in loop. Debugging undoubtedly required!
  댓글 수: 10
Tarmo Tukiainen
Tarmo Tukiainen 2020년 1월 28일
Ah yes that's similar to what I had in mind!
My complete code is the following and the above shown results are with this.
t = TT_bat_KG ;
t.Level=zeros(height(t),1);
C = 500; % Capacity level
t.Level=cumsum(t.("Total[kg/d]")) ;
i1 = 1;
i2 = find(t.Level >= C,1);
while i2 <= height(t)
i1 = i2 + 1;
t.Level(i1:end) = t.Level(i1:end) - t.Level(i1);
t.Level(i1:end)=cumsum(t.("Total[kg/d]")(i1:end));
i2 = find(cumsum(t.("Total[kg/d]")(i1:end))>=C,1) + i1;
end
In my eyes it should indeed restart immediately. I have tried to switch the >= sign into both == and <= signs, but then I get an error regarding indexing (Index exceeds the number of array elements (365) & Error in tabular/dotParenReference, b = b(rowIndiced).
Any idea what might be wrong with the code?
dpb
dpb 2020년 1월 28일
Yeah, there's an "off by one" logic error in the adjustment for the offset from origin in the calculation of i2; use
i2 = find(cumsum(t.("Total[kg/d]")(i1:end))>=C,1) + i1-1;
instead. i2 is from origin of the subset vector which is one-based so the offset is/needs be 0-based.

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

카테고리

Help CenterFile Exchange에서 Data Type Identification에 대해 자세히 알아보기

제품


릴리스

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by