Поместите несколько событий временного ряда из объекта группы pandas в один график. - PullRequest
0 голосов
/ 07 марта 2019

У меня есть вопрос, связанный с временными рядами, о том, как наносить метки времени вдоль горизонтальной оси для нескольких случаев, приписываемых одному и тому же лицу. Позвольте мне объяснить:

Допустим, у нас есть Джейсон и Джорджия. Оба они работают в разных случаях, которые в основном имеют эти потенциальные «события»: начало, пауза, возобновление, конец. Во многих случаях есть только «начало» и «конец», тогда как другие также включают интервал паузы-возобновления. Пока один случай приостановлен, пользователь может работать над другим делом. У меня есть вся эта информация на Pandas DataFrame, и я собираю информацию на уровне пользователей и дел, выполняя groupby.

Пример данных для воспроизводимого кода (при условии, что импортированы pandas и numpy):

raw_data = {'user': ['Jason', 'Georgia', 'Jason', 'Jason', 'Georgia'], 
    'case': ['a', 'b', 'c', 'd', 'e'], 
    'date_picked_up': ['2018-10-25 14:06', '2019-01-25 10:44', '2019-01-25 09:14', '2019-01-25 12:12', '2019-02-21 10:01'], 
    'date_paused': ['2018-10-26 11:08', '2019-01-25 12:11', np.nan, np.nan, '2019-02-21 12:37'],
    'date_resumed': ['2018-10-26 11:20', '2019-01-25 15:21', np.nan, np.nan, '2019-02-21 13:24'],
    'date_closed': ['2018-10-29 16:57', '2019-01-25 16:34', '2019-01-25 11:46', '2019-01-25 15:24', '2019-01-25 13:56']}
df = pd.DataFrame(raw_data, columns = ['user', 'case', 'date_picked_up', 'date_paused', 'date_resumed', 'date_closed'])
df

Возвращает df, pandas DataFrame с последовательностью каждого случая. Когда у нас нет интервала паузы возобновления, значения np.nan. Панды groupby автоматически игнорируют nan значения, которые нам не нужны, поэтому для решения этой проблемы я использую fillna с Timestamp в 1900 году, после применения ко всем столбцам pd.to_datetime:

date_cols = ['date_picked_up', 'date_paused', 'date_resumed', 'date_closed']
for c in date_cols:
    df[c] = pd.to_datetime(df[c], format='%Y%m%d %H:%M')

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

df.fillna(pd.Timestamp('19000101'))\
  .groupby(['user', 'case', 'date_picked_up', 'date_paused', 'date_resumed', 'date_closed'])[['date_picked_up', 'date_paused', 'date_resumed', 'date_closed']].count()

Моя цель (из данных этого примера) - два графика, один для Джейсона и один для Джорджии, где отметки времени (в идеале, не 1900) будут отображаться вдоль горизонтальных «линий», по одному для каждого случая (на ось). Ближайший пример здесь: Построение помеченных временных рядов в пандах , где вместо собак, кошек и коров у нас были бы (для Джейсона) случаи a, c и d на оси y.

Я нашел идеи о том, как переместить все в bokeh или d3 для того, что я действительно хочу (например: https://github.com/jiahuang/d3-timeline, Как построить график продолжительности событий (диаграммы Ганта) с помощью Python Pandas ? ), но я надеюсь найти решение в Python и Matplotlib / Seaborn, так как считаю, что моя структура данных уже находится в достаточно хорошем формате.

...