Как создать столбец в фрейме данных pandas, который проверяет, произошел ли переход состояния?

#python #pandas #dataframe #data-analysis

#python #pandas #фрейм данных #анализ данных

Вопрос:

Ниже приведен исходный фрейм данных:

  uid    timestamp      state
   1     2015-01-01      fail  
   2     2015-01-07      fail  
   2     2015-03-02      fail  
   1     2015-01-03      pass  
   1     2015-01-02      warn  
   2     2015-03-01      pass  
   1     2015-01-04      pass  
   1     2015-01-07      pass  
   2     2015-01-01      warn  
  

Это результирующий фрейм данных, который я хотел бы сгенерировать:

  uid     timestamp      state  fail->pass?
   1     2015-01-01      fail  True
   2     2015-01-07      pass  False
   2     2015-03-02      fail  False
   1     2015-01-03      pass  True
   1     2015-01-02      warn  True
   2     2015-03-01      pass  False
   1     2015-01-04      pass  True
   1     2015-01-07      pass  True
   2     2015-01-01      warn  False
  

Столбец «Сбой-> Передача?» — это логический столбец, который сообщает вам, перешел ли UID из состояния сбоя в состояние перехода. Это состояние передачи должно быть конечным состоянием UID. Падающее состояние может произойти в любое время перед конечным состоянием. Конечное состояние возникает в последней временной метке для этого UID.

Какой наиболее эффективный способ создать этот столбец? Потенциально могут быть сотни переходов состояний для каждого UID.

Ответ №1:

 df = pd.DataFrame({'uid': [1, 2, 2, 1, 1, 2, 1, 1, 2],
 'timestamp': ['2015-01-01',
  '2015-01-07',
  '2015-03-02',
  '2015-01-03',
  '2015-01-02',
  '2015-03-01',
  '2015-01-04',
  '2015-01-07',
  '2015-01-01'],
 'state': ['fail',
  'pass',
  'fail',
  'pass',
  'warn',
  'pass',
  'pass',
  'pass',
  'warn'],
 'fail->pass?': [True, False, False, True, True, False, True, True, False]})


df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.sort_values(by='timestamp')

fp = (df[['uid','state']].groupby('uid').last()=='pass').reset_index()
fp.columns = ['uid','fail->pass?']

df.merge(fp, on='uid').sort_values(by='timestamp')
  

Вывод

    uid  timestamp   state   fail->pass?
0   1   2015-01-01  fail    True
5   2   2015-01-01  warn    False
1   1   2015-01-02  warn    True
2   1   2015-01-03  pass    True
3   1   2015-01-04  pass    True
4   1   2015-01-07  pass    True
6   2   2015-01-07  fail    False
7   2   2015-03-01  pass    False
8   2   2015-03-02  fail    False
  

Комментарии:

1. Спасибо, это близко! Но, похоже, он смотрит только на то, является ли конечное состояние проходом. Фактически не проверяется, перешел ли UID из состояния сбоя в состояние перехода. Я также хотел бы иметь условие, что если UID не имеет состояния сбоя, то «сбой-> передача?» должно быть False. Другими словами, даже если UID всегда находится в состоянии передачи «сбой-> передача?» должно быть False.