Как составить график агрегированных данных временных рядов с помощью matplotlib - PullRequest
0 голосов
/ 01 февраля 2020

У меня есть CSV-файл ошибок с отметкой времени каждой ошибки. Пример данных выглядит следующим образом:

2020-01-06T02:54:01.012+0000, 500 Internal Server Error
2020-01-06T05:04:01.012+0000, 500 Internal Server Error
2020-01-06T05:44:01.012+0000, 500 Internal Server Error
2020-01-06T07:04:01.013+0000, 500 Internal Server Error
2020-01-06T08:04:01.012+0000, 500 Internal Server Error
2020-01-06T10:24:01.010+0000, 500 Internal Server Error
2020-01-06T17:48:31.192+0000, 503 Service Unavailable
2020-01-08T04:35:48.624+0000, 502 Bad Gateway
2020-01-08T16:56:04.814+0000, 503 Service Unavailable

Я хотел бы использовать matplotlib для отображения ошибок в минуту (или 30 se c) с каждой ошибкой в ​​виде отдельной строки на графике. Не знаете, как сделать агрегацию? Это то, что я пытался. Любая помощь?


import matplotlib.pyplot as plt
import pandas as pd

infile="example.csv"

dateparse = lambda time_str: pd.datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S.%f')
df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse, index_col="datetime", names=['datetime','error'])

df.plot()
plt.show()

1 Ответ

1 голос
/ 01 февраля 2020

Начните с определения следующей функции:

def counts(grp):
    codeList = ['500', '502', '503']
    return pd.Series([np.count_nonzero(grp.eq(code)) for code in codeList],
        index=map(lambda x: 'Err_' + x, codeList))

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

Считайте ваш файл следующим образом:

df = pd.read_csv('your_log.csv', names=['Date', 'Message'],
    skipinitialspace=True, parse_dates=[0])

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

Затем выполните: df.Date = df.Date.dt.tz_localize(None), чтобы удалить часть часового пояса ( + 0000 ) из результата.

Поскольку сравнение полных строк неудобно, я решил сравнивать только коды ошибок (3 начальных символа каждого сообщения). Для этого давайте создадим новый столбец с просто кодами ошибок:

df['Code'] = df.Message.str.slice(0,3)

Следующим шагом будет создание количества ошибок в каждом часе путем повторной выборки и применения вышеуказанной функции к каждой часовой группе:

errCnt = df.resample('1H', on='Date').Code.apply(counts).unstack(level=1)

Если вам нужно другое разрешение по времени, измените 1H на желаемый период.

И последний шаг - добавление столбца Total ( если вам это нужно):

errCnt['Total'] = errCnt.sum(axis=1)

Для моих образцов данных (с некоторыми ошибками, в более коротком периоде) я получил:

                     Err_500  Err_502  Err_503  Total
Date                                                       
2020-01-06 02:00:00        1        0        0      1
2020-01-06 03:00:00        0        0        0      0
2020-01-06 04:00:00        0        0        0      0
2020-01-06 05:00:00        1        2        2      5
2020-01-06 06:00:00        0        0        0      0
2020-01-06 07:00:00        1        0        0      1
2020-01-06 08:00:00        1        0        0      1
...