Automotivo e trabalho com dados

Compare várias condições de teste no mesmo eixo de tempo

Valide três arquivos CSV sintéticos de demonstração e depois sobreponha em um único gráfico as curvas que compartilham as mesmas amostras de tempo e unidades de aceleração.

Ver o sumário

A tradução foi feita com IA. Confira o código, as unidades e os valores junto com o original. A revisão por falantes nativos de cada idioma ainda não foi concluída. English

Para quem éIniciantes em Python na área automotiva que querem sobrepor resultados de testes de várias condições

Preparação
  • Tenha Python 3.12 e um terminal prontos. Verifique a versão com python --version.
  • Extraia todo o ZIP baixado e abra um terminal na pasta que contém example.py.
  • Comece com os dados de prática incluídos e depois compare os resultados com os arquivos originais.
  • case_a.csv, case_b.csv e case_c.csv na pasta inputs são todos dados sintéticos de demonstração.
  • Todas as entradas usam time em s, acceleration em m/s^2 e as mesmas time samples.

01Alinhe as condições necessárias para a comparação

Para sobrepor várias curvas em um único gráfico, time e as units do eixo vertical precisam ter o mesmo significado. Este exemplo representa os dados sintéticos de demonstração Case A, Case B e Case C em eixos comuns de time em s e acceleration em m/s^2. Os nomes das conditions são lidos da coluna condition de cada arquivo.

02Prepare a pasta e o formato de entrada

O script lê os arquivos .csv da pasta inputs em ordem de nome. Deve haver pelo menos dois arquivos, e cada arquivo deve conter apenas uma condition. Cada linha deve ter seis colunas: dataset_note, condition, time, time_unit, acceleration e acceleration_unit.

CampoExemplo incluído
dataset_noteSynthetic demonstration data
conditionCase A (ASCII letters and numbers)
time / time_unit0.0 / s
acceleration / acceleration_unit0.8 / m/s^2

Este exemplo só compara quando os time arrays dos arquivos são exatamente iguais. Ele para se o número de samples, o tempo inicial ou qualquer time value for diferente. O eixo do gráfico mostra a unidade compartilhada como m/s².

03Prepare os arquivos e execute o exemplo

  1. Extraia o ZIP e verifique se o arquivo de entrada listado em README.txt está na mesma pasta que example.py. Não execute o exemplo de dentro do arquivo ZIP.
  2. Execute os comandos abaixo, uma linha por vez, na pasta que contém example.py. No Windows, se python não estiver disponível mas py estiver, substitua python em cada comando por py -3.12.
  3. Depois que a mensagem de conclusão aparecer, abra a nova pasta outputs. Se outputs já existir, renomeie-a primeiro para preservar os resultados anteriores e depois execute o exemplo novamente.
bash
python --version
python -m pip install -r requirements.txt
python example.py

A instalação requer conexão com a internet. BASE no código define os caminhos de entrada e saída em relação a example.py, e não à pasta atual do terminal.

04Código completo e verificações antes da comparação

Depois de verificar o time order e as units em cada arquivo, o script procura nomes de condition duplicados. Ele compara os arrays restantes com o time array do primeiro arquivo e adiciona linhas a um único Axes somente quando todos correspondem. Sorting, time shifting, interpolation e unit conversion não são feitos automaticamente.

example.py
"""Overlay explanatory synthetic test conditions on the same axes.

All files must have the same explicit units and matching time samples.
No interpolation, clock shifting, filtering, or safety assessment is performed.
"""
import csv
import math
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

BASE = Path(__file__).resolve().parent
HEADERS = ["dataset_note", "condition", "time", "time_unit", "acceleration", "acceleration_unit"]
NOTE = "설명용 합성 데이터"


def read_condition(path):
    times, values = [], []
    label = None
    with path.open(encoding="utf-8-sig", newline="") as file:
        reader = csv.DictReader(file)
        if reader.fieldnames != HEADERS:
            raise ValueError(f"{path.name}: expected headers {HEADERS}")
        for line, row in enumerate(reader, start=2):
            if None in row or any(value is None or not value.strip() for value in row.values()):
                raise ValueError(f"{path.name}:{line}: missing or extra field.")
            if row["dataset_note"] != NOTE:
                raise ValueError(f"{path.name}:{line}: synthetic-data label is required.")
            if row["time_unit"] != "s" or row["acceleration_unit"] != "m/s^2":
                raise ValueError(f"{path.name}:{line}: expected units s and m/s^2; no automatic conversion.")
            if not row["condition"].isascii():
                raise ValueError(f"{path.name}:{line}: use an ASCII condition label for portable plotting.")
            label = row["condition"] if label is None else label
            if row["condition"] != label:
                raise ValueError(f"{path.name}:{line}: condition label changes within one file.")
            time, value = float(row["time"]), float(row["acceleration"])
            if not math.isfinite(time) or not math.isfinite(value) or time < 0:
                raise ValueError(f"{path.name}:{line}: expected finite values and nonnegative time.")
            if times and time <= times[-1]:
                raise ValueError(f"{path.name}:{line}: duplicate or decreasing time.")
            times.append(time)
            values.append(value)
    if len(times) < 2:
        raise ValueError(f"{path.name}: at least two samples are required.")
    return label, times, values


def main():
    destination = BASE / "outputs"
    if destination.exists():
        raise ValueError("outputs already exists; rename it before running again.")
    paths = sorted((BASE / "inputs").glob("*.csv"))
    if len(paths) < 2:
        raise ValueError("At least two CSV files are required in inputs.")
    conditions = [read_condition(path) for path in paths]
    if len({label for label, _, _ in conditions}) != len(conditions):
        raise ValueError("Condition labels must be unique across files.")
    reference_times = conditions[0][1]
    if any(times != reference_times for _, times, _ in conditions[1:]):
        raise ValueError("Time samples do not match; check alignment before comparison.")

    figure, axis = plt.subplots(figsize=(8, 4.6), layout="constrained")
    for label, times, values in conditions:
        axis.plot(times, values, marker="o", linewidth=2, label=label)
    axis.set(title="Test conditions | Explanatory synthetic data", xlabel="Elapsed time (s)", ylabel="Acceleration (m/s²)")
    axis.spines[["top", "right"]].set_visible(False)
    axis.grid(alpha=0.2)
    axis.legend(frameon=False)
    destination.mkdir(exist_ok=False)
    with (destination / "comparison_summary.csv").open("x", encoding="utf-8-sig", newline="") as file:
        writer = csv.writer(file)
        writer.writerow(["dataset_note", "condition", "sample_count", "min_acceleration", "max_acceleration", "unit"])
        for label, _, values in conditions:
            writer.writerow([NOTE, label, len(values), min(values), max(values), "m/s^2"])
    figure.savefig(destination / "synthetic_comparison.png", dpi=160)
    plt.close(figure)
    print(f"Explanatory synthetic data: {len(conditions)} conditions, {len(reference_times)} matching time samples each.")
    print("Created outputs/comparison_summary.csv and outputs/synthetic_comparison.png.")


if __name__ == "__main__":
    try:
        main()
    except (OSError, ValueError, csv.Error) as error:
        raise SystemExit(f"Stopped: {error}") from error

05Leia o gráfico e o CSV de resumo

As três conditions são sobrepostas em outputs/synthetic_comparison.png. outputs/comparison_summary.csv armazena o número de samples e a acceleration minimum e maximum de cada condition. Esses números são um resumo simples de dados sintéticos de demonstração.

ConditionSamplesMinimumMaximum
Case A60.0 m/s²1.4 m/s²
Case B60.0 m/s²1.1 m/s²
Case C60.0 m/s²1.7 m/s²
Acceleration comparison of synthetic demonstration data Cases A, B, and C. Three curves using the same 0–1 s time and m/s² axes.
Acceleration comparison of synthetic demonstration data Cases A, B, and C. Three curves using the same 0–1 s time and m/s² axes.

Na sample de 0.4 s, os valores das três curvas são 1.4, 1.1 e 1.7 m/s². As linhas do gráfico conectam as samples; elas não criam novos measured values entre elas.

06Etapas para confirmar que os eixos correspondem

  1. Verifique se Case A, Case B e Case C na legend do gráfico correspondem aos condition values dos arquivos de entrada.
  2. Verifique Elapsed time (s) no x-axis e Acceleration (m/s²) no y-axis.
  3. Compare os valores dos três arquivos CSV em 0.4 s com o gráfico e a summary table.
  4. Em uma nova cópia de prática, altere um time value de case_b.csv para 0.41. Verifique se ele para com a mensagem Time samples do not match.
  5. Em outra nova cópia, altere acceleration_unit para g e verifique se ele para sem fazer conversão automática.

07Descubra por que a comparação para

MensagemO que verificar
expected units s and m/s^2Verifique as units e a notação reais no arquivo exportado.
duplicate or decreasing timeVerifique o time order nesse arquivo e linha.
Time samples do not matchVerifique o tempo inicial, sampling interval e missing samples. Não simplesmente sobrescreva os times sem saber a causa.
Condition labels must be uniqueUse um condition name diferente para cada arquivo.
condition label changesVerifique se um arquivo não mistura várias conditions.
At least two CSV filesVerifique se os arquivos de entrada estão na pasta inputs.

08O que o gráfico sozinho não pode dizer

  • Mesmo com o mesmo time axis numérico, o trigger ou reference time podem ser diferentes. Verifique separadamente a base de alignment em testes reais.
  • Somente time arrays exatamente idênticos são permitidos. Approximate matching, resampling, interpolation e time-delay correction estão fora do escopo.
  • O código não julga se diferentes sensor locations, coordinate systems, sampling filters ou test conditions são comparáveis.
  • O sample maximum não garante o verdadeiro maximum entre samples. O gráfico não fornece pass/fail, performance ranking nem julgamentos de segurança.

Registro de execução e verificação

Windows 11 (10.0.26200), CPython 3.12.14 (64-bit). openpyxl 3.1.5, Matplotlib 3.10.8. As bibliotecas usadas por cada exemplo estão fixadas em requirements.txt.

  • Foram verificados 3 conditions × 6 samples de dados sintéticos de demonstração e os valores minimum e maximum
  • Foram verificados erros de unit mismatch, duplicate ou reversed times, mismatched time arrays e duplicate condition names
  • Foi verificado que os hashes originais permanecem inalterados, que outputs existentes são recusados e que o PNG é criado
Limites da verificação
  • Não foram avaliados a comparabilidade de test conditions reais, time synchronization, measurement uncertainty nem segurança.

Princípios de redação e verificação de todo o site

Arquivos de exemplo para executar

Inclui código, dados de entrada e instruções de execução. Extraia o ZIP e leia primeiro o README.txt.

Baixar ZIP de exemplo

O código de exemplo, os nomes de arquivos e as chaves de entrada são mantidos como no original. Consulte também os comandos e os procedimentos de conferência do texto traduzido.

Material de prática original · Guarde os arquivos originais separadamente antes de executar.

Fontes de referência

As explicações e os exemplos são de elaboração própria. Os comportamentos e conceitos relacionados podem ser consultados nas fontes oficiais abaixo.