Skip to content

profiling

profiling ¤

One-call data-quality and semantics report for long-format time series.

Start every analysis here::

import ts_shape

report = ts_shape.profile(df)
print(report.summary())     # what each signal is, and what is wrong with it
report.issues()             # actionable list, most severe first
report.specs                # SignalSpecs to pass on to detectors

The report infers each signal's semantics (see :mod:ts_shape.signals) and checks the things that silently corrupt industrial analytics: logging gaps, counter resets, duplicate or out-of-order timestamps, unparseable times, missing or non-numeric values, signals stuck at one value, and uuids that spread their values over several value_* columns.

ProfileReport dataclass ¤

ProfileReport(
    specs: SignalSpecs,
    table: DataFrame,
    issue_table: DataFrame,
)

Result of :func:profile.

Attributes:

Name Type Description
specs SignalSpecs

Inferred (and overridden) :class:~ts_shape.signals.SignalSpecs.

table DataFrame

One row per signal with the measured characteristics.

issue_table DataFrame

One row per finding (uuid, severity, issue, detail), most severe first.

Example

import ts_shape report = ts_shape.profile(ts_shape.make_timeseries(["temp", "pressure"], n_points=100)) print(report.summary()) ts-shape profile: 2 signal(s) kinds: 2 continuous issues: none report.to_frame()[["uuid", "kind", "encoding", "rows"]] uuid kind encoding rows 0 pressure continuous sampled 100 1 temp continuous sampled 100

to_frame ¤

to_frame() -> pd.DataFrame

The per-signal table.

issues ¤

issues(severity: str | None = None) -> pd.DataFrame

Findings, optionally filtered to one severity.

Parameters:

Name Type Description Default
severity str | None

"error", "warning" or "info" to keep only that severity. None returns every finding.

None

Returns:

Type Description
DataFrame

DataFrame with columns uuid, severity, issue and detail, most severe first.

summary ¤

summary() -> str

Human-readable overview.

profile ¤

profile(
    dataframe: DataFrame,
    specs: (
        SignalSpecs | Mapping[str, Mapping[str, Any]] | None
    ) = None,
    *,
    uuid_column: str = "uuid",
    time_column: str = "systime"
) -> ProfileReport

Profile every signal in a long-format frame.

Nullable, pyarrow and string dtypes are converted to NumPy dtypes first; a time column that mixes UTC offsets is converted to UTC with a :class:~ts_shape.errors.DataQualityWarning. The input is not changed.

Parameters:

Name Type Description Default
dataframe DataFrame

Long-format data (systime, uuid, value_*).

required
specs SignalSpecs | Mapping[str, Mapping[str, Any]] | None

Known semantics. Either complete :class:SignalSpecs, or {uuid: {field: value}} overrides applied on top of inference.

None
uuid_column str

Column identifying the signal.

'uuid'
time_column str

Timestamp column.

'systime'

Returns:

Type Description
ProfileReport

class:ProfileReport with specs, a per-signal table and the

ProfileReport

issues() list.

Raises:

Type Description
ColumnNotFoundError

When uuid_column or time_column is missing (also for pd.DataFrame()).

ValueError

When specs overrides name unknown fields or invalid values.