Как распределить строки данных pandas неравномерно по временным меткам в зависимости от значения столбца

Например. 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.

Еще раз спасибо за быструю помощь.

Как равномерно распределить строки данных pandas по временным меткам в зависимости от значения столбца

Это помогает с равномерным распределением, я смотрю на неравномерное распределение.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
2 694
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

С 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

Очень приятный :)

mozway 24.05.2024 09:41

В каком-то смысле, если честно ;)

Timeless 24.05.2024 09:44

Спасибо! На случай, если я захочу обобщить решение. т. е. включить столбец фактора. И на его основе создайте дополнительные временные метки. Например, для фактора 11 создайте 11 строк, а для фактора 4 создайте 4. Можете ли вы подсказать, как это возможно. 1 1 1 2 2 3 4 11

GKAK 28.05.2024 08:32

Это будет ваш третий вопрос на подобную тему. Я чувствую, что тебе нужно сделать шаг назад и подумать о том, чего ты на самом деле пытаешься достичь. Затем вы можете открыть новый вопрос.

Timeless 28.05.2024 08:37

Ближе к решению Израэля по ссылке выше:

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)   

Другие вопросы по теме