Объекты Bin datetime.date для создания групп

У меня есть некоторые данные, которые я хотел бы разделить на четыре группы, основанные на определенных моментах времени — моменты времени, заданные определенными датами.

У меня есть такие данные (предположим, что df уже создано):

df["date"] = pd.to_datetime(df["date"], format = "%Y-%m-%d")
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month

df.groupby(by = "year", as_index = False).agg({"month":pd.Series.nunique})
год месяц 2015 3 2016 12 2017 12 2018 12 2019 12 2020 12 2021 12 2022 9

Обратите внимание, что с этими данными 2015 и 2022 годы не являются полными годами.

Я думал, что, поскольку у меня есть данные за 84 месяца (3 + (6*12) + 9 = 84), я мог бы разделить данные на четыре группы, чтобы в каждой группе было всего данных примерно за 21 месяц 84 / 4 = 21.

Чтобы сделать это, я бы сначала начал с самой ранней даты в моем наборе данных, которая равна 2015-10-02. К этим самым ранним данным я бы добавил 21 месяц:

from dateutil.relativedelta import relativedelta

min_date = df["date"].min().date()
print([min_date, min_date + relativedelta(months = 21)]

#output
[datetime.date(2015, 10, 2), datetime.date(2017, 7, 2)]

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

Вторая группа попадет в диапазон дат, где минимальная дата будет на один день больше, чем максимальная дата диапазона дат предыдущей группы:

"2017-07-02" + relativedelta(days = 1) = "2017-07-03"

Это гарантирует, что бины разных групп не перекрываются.

В последней группе будет немного меньше данных, так как она будет включать данные до последней даты во всем наборе данных, которая составляет 2022-09-30

В целом, корзины диапазона дат для разных групп будут выглядеть примерно так

Группа Диапазон дат А "2015-10-02", "2017-07-02" Б "2017-07-03", "2019-04-03" С "2019-04-04", "2021-01-04" Д "2021-01-05", "2022-9-30"

Я знаю, что могу найти эти диапазоны дат вручную и использовать их для фильтрации набора данных для создания групп с помощью np.select, но это не очень эффективно.

df["Group"] = np.select(
    condlist = [
        (df["date"] >= "2015-10-02") & (df["date"] <= "2017-07-02"),
        (df["date"] >= "2017-07-03") & (df["date"] <= "2019-04-03"),
        (df["date"] >= "2019-04-04") & (df["date"] <= "2021-01-04"),
        (df["date"] >= "2021-01-05") & (df["date"] <= "2022-09-30")
    ],
    choicelist = ["A", "B", "C", "D"]
)

Конечно, должен быть способ найти эти значения (так, как я хочу) без необходимости находить их вручную.

Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
107
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете взглянуть на pd.cut.

# toy data
df = pd.DataFrame(pd.date_range('2020-01-01', '2022-01-01'), columns = ['date'])

          date
0   2020-01-01
1   2020-01-02
2   2020-01-03
3   2020-01-04
4   2020-01-05
..         ...

Вы можете создать метки и границы для бункеров.

from numpy import datetime64
bin_labels = [1, 2, 3, 4]
cut_bins = [datetime64('2019-12-31'), datetime64('2020-04-01'), datetime64('2020-12-31'), datetime64('2021-09-01'), datetime64('2022-01-01')]

И сохраните корзины в новый столбец.

df['cut'] = pd.cut(df['date'], bins = cut_bins, labels = bin_labels]

          date cut
0   2020-01-01   1
1   2020-01-02   1
2   2020-01-03   1
3   2020-01-04   1
4   2020-01-05   1
..         ...  ..
727 2021-12-28   4
728 2021-12-29   4
729 2021-12-30   4
730 2021-12-31   4
731 2022-01-01   4

Надеюсь, поможет.

Спасибо за ваш ответ, функция numpy datetime64 была функцией, которая помогла мне получить ответ, который я хотел

JoMcGee 25.11.2022 09:01
Ответ принят как подходящий

Я нашел способ, который, как мне кажется, работает (для тех, кто может быть заинтересован в объединении значений даты и времени в будущем) - предположим, что данные такие же, как указано в описании вопроса:

from dateutil.relativedelta import relativedelta
import numpy as np

dates = []
start = df["date"].min().date()
dates.append(np.datetime64(start))
while start <= df["date"].max().date():
    start = start + relativedetla(months = 21)
    dates.append(np.datetime64(start))

df["Group"] = pd.cut(
    df["date"], bins = dates,
    labels = ["A", "B", "C", "D"],
    right = False #right = False ensures no group overlap in date values
)

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

Clean_list() --> ValueError: неверное количество переданных элементов 3, размещение подразумевает 1
Как изменить сокращенные слова в столбце в Python, например, NY на New York, US на United States одновременно?
Манипулировать строковыми данными в файл excel
Анализ ассоциации рыночной корзины python или SQL
Панды интерполируют внутри группы для одного столбца
Создайте новые столбцы, используя уникальные значения в других столбцах в Python
Pandas Отделите категориальные и числовые функции от нескольких фреймов данных и сохраните их в новом фрейме данных
Вычисление общего количества значений на основе одного и того же идентификатора в фрейме данных pandas
Загрузка большого файла (800 МБ) с URL-адреса в корзину GCS с использованием облачной функции
Как показать текст из третьего столбца фрейма данных при наведении курсора на линейную диаграмму, состоящую из двух других столбцов?

Похожие вопросы