Построить датафрейм с несколькими CSV

Вопрос или проблема

Я собираю метрики по 6 REST-сервисам из архитектуры микросервисов. Для каждого собранного момента я извлекаю два CSV-файла из каждого сервиса. Один CSV содержит три метрики задержки (99-й процентиль, 50-й процентиль, среднее значение). А другой CSV содержит количество ответов в секунду, которые сервис вернул с HTTP-кодами 200 и 400.

Примеры каждого из CSV:

Задержка:

"Время", "99-й процентиль", "50-й процентиль", "Среднее", "Ошибка"
2023-02-23 15:20:30,2.45,0.577,0.602,True
2023-02-23 15:21:00,0.939,0.424,0.457,True
2023-02-23 15:21:30,0.740,0.417,0.456,True
2023-02-23 15:22:00,0.965,0.396,0.443,True
2023-02-23 15:22:30,2.34,0.438,0.547,True

QPS:

"Время","2xx","4xx/5xx","Ошибка"
2023-02-22 21:18:30,216,0,False
2023-02-22 21:19:00,280,0,False
2023-02-22 21:19:30,242,0,False
2023-02-22 21:20:00,311,0,False

В дополнение к метрикам есть столбец с Временем и столбец с отметкой, является ли это булевым значением.

Имена CSV-файлов всегда начинаются с названия сервиса и содержат слово “latency” в случае метрик задержки и “QPS” в случае запрашиваемого за секунду.

Пример:

Cart latency-data-as-seriestocolumns-2023-02-23 15_53_38.csv
Cart QPS-data-2023-02-23 15_53_26.csv
Catalogue latency-data-as-seriestocolumns-2023-02-23 15_53_20.csv
Catalogue QPS-data-2023-02-23 15_53_13.csv
Frontend latency-data-as-seriestocolumns-2023-02-23 15_54_54.csv
Frontend QPS-data-as-seriestocolumns-2023-02-23 15_54_48.csv
Orders latency-data-as-seriestocolumns-2023-02-23 15_53_54.csv
Orders QPS-data-2023-02-23 15_53_47.csv
Payment latency-data-as-seriestocolumns-2023-02-23 15_54_10.csv
Payment QPS-data-2023-02-23 15_54_00.csv
Shipping latency-data-as-seriestocolumns-2023-02-23 15_54_24.csv
Shipping QPS-data-2023-02-23 15_54_17.csv
User latency-data-as-seriestocolumns-2023-02-23 15_54_40.csv
User QPS-data-as-seriestocolumns-2023-02-23 15_54_32.csv

Я хотел сделать набор данных, в котором читаются все CSV из вставки и создается весь набор данных для обучения и валидации.

В конце концов, у меня будет набор данных со следующим форматом:

"Время","99-й процентиль","50-й процентиль","Среднее","2xx","4xx/5xx","Ошибка","Сервис"
2023-02-06 16:13:00,0.0970,0.00402,0.00771,254,0,True,Orders
2023-02-06 16:13:30,0.0700,0.00377,0.00614,267,0,True,Orders
2023-02-06 16:14:00,0.0208,0.00328,0.00388,251,0,True,Orders
2023-02-06 16:14:30,0.0971,0.00349,0.00655,273,0,True,Orders
2023-02-06 16:15:00,0.0232,0.00323,0.00443,276,0,True,Orders
2023-02-06 16:15:30,0.00995,0.00309,0.00380,69,0,True,Orders
2023-02-06 16:16:00,0.00957,0.00283,0.00316,171,0,True,Orders

Можно ли собрать всю эту информацию в одном DataFrame? Учитывая, что собранный момент представлен двумя CSV, и что в одной папке у меня будет несколько периодов сбора времени.

Если я правильно понимаю ваш вопрос, это должно дать вам то, что вы ищете:

from glob import glob

dfs = {'latency': [], 'qts': []}

for file_path in glob('*.csv'):
    service, data_type = file_path.split('_')[0:2]
    df = pd.read_csv(file_path)
    df['Service'] = service
    df = df.rename(columns={'IsError': f'IsError_{data_type}'})
    dfs[data_type].append(df)

# объединить все датафреймы для задержки и qts
latency, qts = pd.concat(dfs['latency']), pd.concat(dfs['qts'])

# присоединить задержку и qts по Сервису и Времени
dataset = qts.join(latency, on=['Service', 'Timestamp'], how='inner').reset_index()

# это предполагает, что ошибка возникает, если либо задержка, либо qts является ошибкой
dataset['IsError'] = dataset['IsError_latency'] | dataset['IsError_qts']
dataset = dataset.drop(columns=['IsError_latency', 'IsError_qts'])

Ответ или решение

Для создания единого DataFrame, который объединит метрики из нескольких CSV файлов, содержащих данные о латентности и количестве ответов на HTTP коды, следуйте данному пошаговому руководству. Этот процесс поможет вам собрать и структурировать данные из микросервисной архитектуры для дальнейшего анализа и обучения моделей.

Шаг 1: Подготовка окружения

Для начала убедитесь, что у вас установлены необходимые библиотеки. Мы используем pandas для работы с данными и glob для поиска файлов.

import pandas as pd
from glob import glob

Шаг 2: Чтение и группировка CSV файлов

Создадим два списка, в которых будут храниться DataFrame для метрик латентности и QPS. Каждый файл будет загружен в соответствующий DataFrame, а также добавлена информация о сервисе.

# Словарь для хранения DataFrame по типу данных
dfs = {'latency': [], 'qps': []}

# Итерация по всем CSV файлам в текущей директории
for file_path in glob('*.csv'):
    # Определение названия сервиса и типа данных
    service = file_path.split(' ')[0]  # Первое слово в имени файла
    if 'latency' in file_path:
        data_type = 'latency'
    elif 'QPS' in file_path:
        data_type = 'qps'
    else:
        continue  # Пропустить файлы, которые не соответствуют шаблону

    # Чтение CSV файла
    df = pd.read_csv(file_path)
    df['Service'] = service  # Добавление колонки с названием сервиса
    df = df.rename(columns={'IsError': f'IsError_{data_type}'})  # Переименование колонки IsError для уникальности
    dfs[data_type].append(df)  # Добавление DataFrame в список по типу данных

Шаг 3: Объединение DataFrame

После того как вы прочитали все CSV файлы из директории, необходимо объединить их в один общий набор данных. Для этого мы сначала объединим DataFrame по каждому типу метрик, а затем сделаем внутреннее соединение (inner join) по времени и имени сервиса.

# Объединение всех DataFrame по латентности и QPS
latency_df = pd.concat(dfs['latency'])
qps_df = pd.concat(dfs['qps'])

# Приведение форматов времени колонки 'Time' к одному виду для объединения
latency_df['Time'] = pd.to_datetime(latency_df['Time'])
qps_df['Time'] = pd.to_datetime(qps_df['Time'])

# Объединение на основе 'Service' и 'Time'
combined_df = pd.merge(qps_df, latency_df, on=['Time', 'Service'], how='inner')

# Обработка ошибок: создадим единую колонку, которая будет содержать информацию об ошибках
combined_df['IsError'] = combined_df['IsError_qps'] | combined_df['IsError_latency']

Шаг 4: Завершение и вывод данных

На финальном этапе можно удалить колонки с отдельными статусами ошибок, если они не нужны, и вывести итоговый DataFrame или сохранить его в файл.

# Удаление отдельных колонок IsError
combined_df = combined_df.drop(columns=['IsError_qps', 'IsError_latency'])

# Вывод итогового DataFrame
print(combined_df)

# (Опционально) Сохранение результата в новый CSV файл
combined_df.to_csv('combined_metrics.csv', index=False)

Заключение

Следуя этим шагам, вы сможете эффективно собрать и объединить метрики из разных CSV файлов в один DataFrame, что значительно упростит дальнейшие анализы и обучение моделей. Этот подход легко адаптируется под различные условия, включая расширение численности сервисов или изменение структуры данных.

Оцените материал
Добавить комментарий

Капча загружается...