I have the arrival and departure dates of ships arriving at ports consuming power while berthing. I just want to accumulate their power requirement to know the total consumed power at port per minute.
For example:
Ship1 arrives 1/1/2019 at 02:10 and departs at 1/1/2019 at 22:25 and needs 100 kW.
Ship2 arrives 1/1/2019 at 16:35 and departs at 2/1/2019 at 08:10 and needs 150 kW. and so on.
I want to know the required power to be supplied by the port to them with time in minutes for example. So, I can have the total supplied power by the port to ships on y-axis in kW and time in minutes on the y-axis. Is there a smart way to do this in MATLAB or Python ? Many thanks in advance
Regardless of the programming language, the idea is simply to convert the difference array to the original array.
To be specific, assume the data is structured in Python like
data = [
(datetime(2019, 1, 1, 2, 10), datetime(2019, 1, 1, 22, 25), 100),
(datetime(2019, 1, 1, 16, 35), datetime(2019, 1, 2, 8, 10), 150)
]
The following codes get the time and power when a ship arrives or leaves,
from itertools import accumulate
from collections import defaultdict
import matplotlib.pyplot as plt
# Compute changes of power
dic = defaultdict(int)
for arrive, depart, power in data:
dic[arrive] += power
dic[depart] -= power
# Sort by date
x, y = zip(*sorted(dic.items(), key=lambda i: i[0]))
# Convert to original power
y = accumulate((0,) + y)
# Plot
plt.plot(
[t for t in x for _ in range(2)],
[p for p in y for _ in range(2)][1:-1],
'o-'
)
... or in Matlab (duplicated timestamps are not removed for simplicity):
% Changes of power
x = [T.arrive; T.depart];
y = [T.power; -T.power];
% Sort by date
[x,I] = sort(x);
y = y(I);
% Convert to original power
y = cumsum(y);
% Plot
stairs(x, y, 'o-');
result:
Alternatively, if you need the power of every minute, do
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(data, columns=('arrive', 'depart', 'power'))
xmin = df.arrive.min() - np.timedelta64(4, 'h')
xmax = df.depart.max() + np.timedelta64(4, 'h')
x = np.arange(xmin, xmax, np.timedelta64(1, 'm'))
y = np.zeros(x.shape)
np.add.at(y, (df.arrive - xmin).to_numpy().astype('timedelta64[m]').astype(int), +df.power)
np.add.at(y, (df.depart - xmin).to_numpy().astype('timedelta64[m]').astype(int), -df.power)
y = np.cumsum(y)
plt.plot(x, y, 'o-')
... or in Matlab:
xmin = min(T.arrive) - hours(4);
xmax = max(T.depart) + hours(4);
x = xmin:minutes(1):xmax;
y = zeros(size(x));
arrive_inds = minutes(T.arrive - xmin) + 1;
depart_inds = minutes(T.depart - xmin) + 1;
for i = 1:height(T)
y(arrive_inds(i)) = y(arrive_inds(i)) + T.power(i);
y(depart_inds(i)) = y(depart_inds(i)) - T.power(i);
end
y = cumsum(y);
plot(x, y, 'o-');
result: