Например. DF, который содержит количество выполнений по временным меткам.
DateTime Execution
0 2023-04-03 07:00:00 11
1 2023-04-03 11:00:00 1
2 2023-04-03 12:00:00 1
3 2023-04-03 14:00:00 3
4 2023-04-03 18:00:00 1
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5080 entries, 0 to 5079
Ниже приведен результат, которого я пытаюсь достичь
DateTime Execution
0 2023-04-03 07:00:00 4
1 2023-04-03 08:00:00 4
2 2023-04-03 09:00:00 3
3 2023-04-03 11:00:00 1
4 2023-04-03 12:00:00 1
5 2023-04-03 14:00:00 3
6 2023-04-03 18:00:00 1
Только если исполнение больше 4, его следует распределить на следующие часы. Максимум за любой час — 4.
Еще раз спасибо за быструю помощь.
Это помогает с равномерным распределением, я смотрю на неравномерное распределение.






С asfreq / клипом :
N, C = 4, "Execution"
asfreq = df.set_index("DateTime").asfreq("h")
out = (
(gby:=asfreq.groupby(asfreq[C].notna().cumsum()))[C]
.transform("first")
.sub(gby.cumcount() * N)
.clip(upper=N)
.loc[lambda s: s.gt(0)]
.reset_index(name=C)
.convert_dtypes()
)
Выход :
DateTime Execution
0 2023-04-03 07:00:00 4
1 2023-04-03 08:00:00 4
2 2023-04-03 09:00:00 3
3 2023-04-03 11:00:00 1
4 2023-04-03 12:00:00 1
5 2023-04-03 14:00:00 3
6 2023-04-03 18:00:00 1
В каком-то смысле, если честно ;)
Спасибо! На случай, если я захочу обобщить решение. т. е. включить столбец фактора. И на его основе создайте дополнительные временные метки. Например, для фактора 11 создайте 11 строк, а для фактора 4 создайте 4. Можете ли вы подсказать, как это возможно. 1 1 1 2 2 3 4 11
Это будет ваш третий вопрос на подобную тему. Я чувствую, что тебе нужно сделать шаг назад и подумать о том, чего ты на самом деле пытаешься достичь. Затем вы можете открыть новый вопрос.
Ближе к решению Израэля по ссылке выше:
import pandas as pd
import datetime
values = [11, 2, 4, 1, 1, 1, 1, 1]
datetimes = [
datetime.datetime.now() + datetime.timedelta(hours=i * 3)
for i in range(len(values))
]
df = pd.DataFrame(
{
"DateTime": datetimes,
"Execution": values,
}
)
boundary = 4
div, mod = df.Execution.divmod(boundary)
num_repeat = div * (mod > 0)
new = df.loc[df.index.repeat(num_repeat)].assign(
Execution=lambda x: ((x.groupby(level=0).cumcount() + 1) < div[x.index]).apply(
lambda y: boundary if y else mod[x.index].drop_duplicates()[0]
),
DateTime=lambda x: x["DateTime"]
+ pd.to_timedelta(x.groupby(level=0).cumcount() + 1, unit = "h"),
)
df_modified = df.copy()
df_modified.loc[df_modified.Execution > 4, "Execution"] = 4
res = pd.concat([df_modified, new]).sort_values("DateTime").reset_index(drop=True)
Очень приятный :)