Process time series data and validate/infer timestamp parameters.
Normalizes grouped and ungrouped time series into the same training path.
When no group column is configured, a reserved pseudo-group column
(PSEUDO_GROUP_COLUMN) is added so the whole dataset is treated as one
sequence. Timestamp format and interval metadata inferred here are saved
back into the resolved config for generation.
This function:
1. Creates a timestamp column if one doesn't exist
2. Validates the timestamp column exists and has no missing values
3. Sorts the data by timestamp
4. Infers timestamp_format from the data
5. Validates or infers timestamp_interval_seconds
6. Sets start_timestamp and stop_timestamp
Parameters:
| Name |
Type |
Description |
Default |
training_df
|
DataFrame
|
|
required
|
config
|
SafeSynthesizerParameters
|
The configuration object with time_series settings
|
required
|
Returns:
Raises:
| Type |
Description |
ParameterError
|
If the timestamp column is missing, if timestamp_format="elapsed_seconds"
is set on a non-numeric column, or if an explicit format fails to parse the data.
|
DataError
|
If the timestamp column has missing values or intervals are inconsistent.
|
Source code in src/nemo_safe_synthesizer/training/timeseries_preprocessing.py
| def process_timeseries_data(
training_df: pd.DataFrame,
config: SafeSynthesizerParameters,
) -> tuple[pd.DataFrame, SafeSynthesizerParameters]:
"""Process time series data and validate/infer timestamp parameters.
Normalizes grouped and ungrouped time series into the same training path.
When no group column is configured, a reserved pseudo-group column
(``PSEUDO_GROUP_COLUMN``) is added so the whole dataset is treated as one
sequence. Timestamp format and interval metadata inferred here are saved
back into the resolved config for generation.
This function:
1. Creates a timestamp column if one doesn't exist
2. Validates the timestamp column exists and has no missing values
3. Sorts the data by timestamp
4. Infers timestamp_format from the data
5. Validates or infers timestamp_interval_seconds
6. Sets start_timestamp and stop_timestamp
Args:
training_df: The training DataFrame.
config: The configuration object with time_series settings
Returns:
Tuple of (processed DataFrame, updated config)
Raises:
ParameterError: If the timestamp column is missing, if ``timestamp_format="elapsed_seconds"``
is set on a non-numeric column, or if an explicit format fails to parse the data.
DataError: If the timestamp column has missing values or intervals are inconsistent.
"""
ts_config = config.time_series
original_group_column = config.data.group_training_examples_by
original_timestamp_column = ts_config.timestamp_column
validation = validate_timeseries_data(training_df, config)
training_df = validation.data
if original_group_column is None:
logger.info("No group column specified, treating entire dataset as a single sequence")
if original_timestamp_column is None:
logger.info(f"Added timestamp column '{validation.timestamp_column}' with elapsed seconds")
config.data.group_training_examples_by = validation.group_by_column
config.data.order_training_examples_by = validation.timestamp_column
ts_config.timestamp_column = validation.timestamp_column
ts_config.timestamp_format = validation.timestamp_format
ts_config.timestamp_interval_seconds = validation.timestamp_interval_seconds
ts_config.start_timestamp = validation.start_timestamp
ts_config.stop_timestamp = validation.stop_timestamp
is_elapsed_time = validation.is_elapsed_time
logger.info(f"Resolved time-series timestamp format: {validation.timestamp_format}")
if validation.timestamp_interval_seconds is not None:
logger.info(f"Resolved timestamp_interval_seconds: {validation.timestamp_interval_seconds}s")
logger.info(
f"Time series range (consistent across {len(validation.group_stats)} groups): "
f"{validation.start_timestamp} to {validation.stop_timestamp}",
)
# Step 7: Convert timestamp back to string format
# Skip string conversion for elapsed_seconds format (values are already numeric)
if (
not is_elapsed_time
and ts_config.timestamp_format is not None
and ts_config.timestamp_format != "elapsed_seconds"
):
training_df[ts_config.timestamp_column] = training_df[ts_config.timestamp_column].dt.strftime(
ts_config.timestamp_format
)
return training_df, config
|