Отдельные строки на основе временных меток

Мой набор данных выглядит так:

      main_id            time_stamp                        
          aaa            2019-05-29 08:16:05+05     
          aaa            2019-05-30 00:11:05+05     
          aaa            2020-05-30 09:15:07+05     
          bbb            2019-05-29 09:11:05+05     

Для каждого main_id я хочу:

а) отсортировать time_stamps в порядке возрастания

б) Я хочу создать новый столбец day, который использует time_stamp для получения числа, описывающего рабочий день.

Рабочие дни определяются следующим образом:

Понедельник 05:00 - Вторник 01:00 (1 рабочий день, т.е. понедельник)

вторник 05:00 - среда 01:00 => (1 рабочий день, т.е. вторник)

и так далее...

Первая и вторая строки со значком main_id = aaa относятся к одному и тому же рабочему дню, поскольку вторая строка показывает время до 1:00 следующего дня. Итак, это самый первый рабочий день, и в столбце day будет 1.

Однако в третьей строке отметка времени относится к другому рабочему дню, поэтому мы добавляем 2 вместо day.

Конечный результат может выглядеть примерно так:

      main_id        time_stamp                             day
          aaa            2019-05-29 08:16:05+05              1
          aaa            2019-05-30 00:11:05+05              1
          aaa            2020-05-30 09:15:07+05              2
          bbb            2019-05-29 09:11:05+05              1

День 1 будет где-то между 5:00 утра и 1:00 следующего дня. В то время как днем ​​​​2 будет следующий возможный рабочий день (следующие 5:00 - 1:00)

Как я могу этого добиться?

df = df.sort_values('vehicle_id')

Что должно происходить между 1 и 5 часами ночи?

mozway 23.04.2022 15:42

ничего. Я предполагаю, что между этими временными интервалами нет данных @mozway

Jbd 23.04.2022 15:44

Тогда должно сработать простое вычитание, см. мой ответ

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

Ответы 2

  1. Чтобы отсортировать временные метки в порядке возрастания, сделайте следующее:
#Let's say the dataframe is df
df['time_stamp'] = pd.to_datetime(df['time_stamp'])
df.sort_values(by='time_stamp')
  1. В рабочие дни я бы сделал так:
day1= #add the end of the first businesss date, like:  2019-05-30 01:00
df['day']=1
for i in df.index:
    df['day'].iloc[i]+=ceil(df['day'].iloc[i] - day1)

При сортировке по отметкам времени я также хочу убедиться, что группировка main_id остается неизменной.

Jbd 23.04.2022 15:43

Кроме того, я не знаю, чем закончился первый рабочий день. придется извлечь его из df

Jbd 23.04.2022 15:43
Ответ принят как подходящий

Простым методом было бы вычесть 5 часов, а затем сгруппировать по отсортированным датам, чтобы получить номер группы:

df['time_stamp'] = pd.to_datetime(df['time_stamp'])
s = df['time_stamp'].sub(pd.Timedelta('5h'))
df['day'] = df.groupby(s.dt.date).ngroup().add(1)

NB. на самом деле вам не нужно сортировать значения, groupby сортирует значение по умолчанию.

Вариант для применения на «main_id»:

df['day'] = (df.groupby('main_id')
               .apply(lambda d: d.groupby(s.dt.date).ngroup().add(1)).droplevel(0)
            )

Выход:

  main_id                time_stamp  day
0     aaa 2019-05-29 08:16:05+05:00    1
1     aaa 2019-05-30 00:11:05+05:00    1
2     aaa 2020-05-30 09:15:07+05:00    2
3     bbb 2019-05-29 09:11:05+05:00    1

не могли бы вы немного объяснить свой код? почему ты вычитаешь 5?

Jbd 23.04.2022 16:36

Чтобы привести свой рабочий день в соответствие с обычным днем, начав на 5 часов раньше: 5->1 становится 0->20 (здесь вы можете вычесть только 1 час).

mozway 23.04.2022 17:11

Было бы здорово, если бы вы могли объяснить немного больше... также часть ngroup(). ТАКЖЕ, с текущим кодом временные метки не сортируются в порядке возрастания. Как я могу достичь этого? Таким образом, элементы по-прежнему сгруппированы по main_id во всех aaa вместе, а затем все bbb вместе. Я уже отсортировал main_ids перед вашим фрагментом кода, как показано в qs

Jbd 23.04.2022 17:12

Сейчас отключаюсь, уточню позже

mozway 23.04.2022 17:16

Чтобы отсортировать даты, просто используйте df = df.sort_values(by=['main_id','time_stamp'])

mozway 24.04.2022 00:18

не могли бы вы объяснить эту часть немного больше? df.groupby(s.dt.date).ngroup().add(1)

Jbd 24.04.2022 17:59

Конечно, для каждой группы (здесь каждая дата) получите номер группы (от 0 до n-1) и добавьте 1, так как вы хотите, чтобы ваш счет начинался с 1.

mozway 24.04.2022 20:37

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