Получить первое вхождение после определенной строки в DataFrame

Мои вопросы по этой теме двоякие (выделены жирным шрифтом): Я использую Dataframe для управления большим объемом данных в следующем формате:

Время Данные 1 Начинать 2 1 3 2 4 3 5 р 6 А 7 Начинать 8 3 9 р

Цель состоит в том, чтобы создать новый столбец, в котором будет храниться разница во времени от первого сообщения после сообщения «Старт» до первого сообщения «R». Этот цикл шаблона «Начало» для «Начала» повторяется тысячи раз в фрейме данных. Я помечаю строки, которые содержат первое после сообщения «Пуск», используя следующий код:

df['Shift'] = df['Data'].shift()
df['first_in_cycle'] = df['Shift'].str.contains('Start')
df.drop(columns='Shift', inplace=True)

Затем я пытаюсь отметить первое вхождение 'R, используя следующий код:

counter = (df['Data'].str.contains('Start')).cumsum()
first_r = df[df['Data'].str.contains('R')].groupby(counter).transform('idxmin')
df.loc[first_r.index, 'first_R'] = True

Однако результатом этого является фрейм данных, в котором все сообщения «R» помечены как истинные, что неверно. Я не знаю, как решить эту проблему.

План состоял в том, чтобы исправить оба столбца флагов, а затем объединить их с помощью .any(), удалив все строки, помеченные как ложные, а затем использовать .diff() для вычисления разницы между «R» и «Start». Это лучший способ добиться этого?

Ниже приведен желаемый результат для исходного примера:

Время Данные Разница во времени 1 Начинать 2 1 5 р 3 7 Начинать 8 3 9 р 1

Всегда ли за сообщением R следует Start? Я имею в виду, всегда ли есть фиксированный шаблон Start -> R -> Start -> R?

Shubham Sharma 14.02.2023 07:06

@ShubhamSharma Между запусками всегда будет как минимум 1 сообщение R. Их может быть несколько или только один. Гарантия хоть одна. Мы

roberthayek 14.02.2023 07:35
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
2
2
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Использовать:

#create default index if necessary
df = df.reset_index(drop=True)
#check Start and R
m1 = df['Data'].str.contains('Start')
m2 = df['Data'].str.contains('R')
#groups by Start
g = m1.cumsum()
#get first R per groups to mask
mask1 = m2.groupby(g).transform('idxmax').eq(df.index)
#get Start + one row after Start
mask2 = m1.groupby(g).shift(fill_value=True)
#boolean indexing
df = df[mask1 | mask2]

#get difference per groups
df['Time Difference'] = df['Time'].groupby(g).diff().mask(mask2)

print (df)
   Time   Data  Time Difference
0     1  Start              NaN
1     2      1              NaN
4     5      R              3.0
6     7  Start              NaN
7     8      3              NaN
8     9      R              1.0

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