Skip to content

detect_trends

End-to-End Trend Detection

detect_trends(df, date_col, value_col, plot=True, method_params=None, debug=False)

This is the main function that runs trend detection end-to-end.

It runs the full PyTrendy pipeline in five stages: signal smoothing, segment extraction, boundary refinement, metric analysis, and optional visualization. It returns a PyTrendyResults object containing ranked, classified, and trend segments, ready for filtering, plotting, or export. Furthermore, it identifies patterns such as uptrends, downtrends, flat regions, and noise by applying rolling statistics, segmentation heuristics, and post-processing refinements. It optionally visualizes the results and returns a structured object containing segment metadata.

The pipeline includes:

  1. Signal Processing: Applies Savitzky-Golay smoothing and computes flags for flat and noisy regions.
  2. Segmentation: Extracts contiguous segments based on signal classification.
  3. Refinement: Adjusts segment boundaries and classifies trends as gradual or abrupt.
  4. Analysis: Computes metrics like total change, percent change, and signal-to-noise ratio.
  5. Visualization (optional): Plots the original signal with annotated segments.

Parameters:

  • df

    (DataFrame) –

    Input time series data containing at least the specified date_col and value_col. The date_col must contain datetime-like values (daily frequency recommended).

  • date_col

    (str) –

    Name of the column representing timestamps. This column is converted to datetime and set as the index.

  • value_col

    (str) –

    Name of the column containing the primary signal to analyze for trend detection.

  • plot

    (bool, default: True ) –

    If True, generates a matplotlib plot showing the detected trend segments over the original signal. Defaults to True.

  • method_params

    (dict, default: None ) –

    Optional parameters to customize detection heuristics. Supported keys:

    • is_abrupt_padded (bool): Whether to pad abrupt transitions between segments. Defaults to False.
    • abrupt_padding (int): Number of days to pad around abrupt transitions. Only referenced when is_abrupt_padded is True. Defaults to 28.
  • debug

    (bool, default: False ) –

    If True will run in debug mode, outputting various additional plots and print statements. Only recommended for developers of pytrendy. Defaults to False.

Returns:

  • PyTrendyResults ( PyTrendyResults ) –

    An object encapsulating the detected segments and associated metadata. Use this object to access segment statistics, rankings, and export utilities.

Source code in pytrendy/detect_trends.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def detect_trends(df: pd.DataFrame, date_col: str, value_col: str, plot=True, method_params: dict=None, debug: bool=False ) -> PyTrendyResults:
    """
    This is the main function that runs trend detection end-to-end.

    It runs the full PyTrendy pipeline in five stages: signal smoothing, segment extraction, boundary refinement, metric analysis, and optional visualization. 
    It returns a `PyTrendyResults` object containing ranked, classified, and trend segments, ready for filtering, plotting, or export. 
    Furthermore, it identifies patterns such as uptrends, downtrends, flat regions, and noise by applying rolling statistics, segmentation heuristics, and post-processing refinements.
    It optionally visualizes the results and returns a structured object containing segment metadata.

    The pipeline includes:

    1. **Signal Processing**: Applies Savitzky-Golay smoothing and computes flags for flat and noisy regions.
    2. **Segmentation**: Extracts contiguous segments based on signal classification.
    3. **Refinement**: Adjusts segment boundaries and classifies trends as gradual or abrupt.
    4. **Analysis**: Computes metrics like total change, percent change, and signal-to-noise ratio.
    5. **Visualization (optional)**: Plots the original signal with annotated segments.

    Args:
        df (pd.DataFrame):
            Input time series data containing at least the specified `date_col` and `value_col`.
            The `date_col` must contain datetime-like values (daily frequency recommended).
        date_col (str):
            Name of the column representing timestamps. This column is converted to datetime and set as the index.
        value_col (str):
            Name of the column containing the primary signal to analyze for trend detection.
        plot (bool, optional):
            If `True`, generates a matplotlib plot showing the detected trend segments over the original signal.
            Defaults to `True`.
        method_params (dict, optional):
            Optional parameters to customize detection heuristics. Supported keys:

            - **is_abrupt_padded** (`bool`): Whether to pad abrupt transitions between segments. Defaults to `False`.
            - **abrupt_padding** (`int`): Number of days to pad around abrupt transitions. Only referenced when `is_abrupt_padded` is `True`. Defaults to `28`.
        debug (bool, optional):
            If `True` will run in debug mode, outputting various additional plots and print statements. Only recommended for developers of pytrendy.
            Defaults to `False`.

    Returns:
        PyTrendyResults:
            An object encapsulating the detected segments and associated metadata.
            Use this object to access segment statistics, rankings, and export utilities.
    """
    df = df.copy()
    df[date_col] = pd.to_datetime(df[date_col])
    df.set_index(date_col, inplace=True)
    df = df[[value_col]]

    # Configures trend detection heuristics
    # Avoid mutable default argument by accepting None and constructing a new dict here
    if method_params is None:
        method_params = {}
    method_params = {
        'is_abrupt_padded': method_params.get('is_abrupt_padded', False),
        'abrupt_padding': method_params.get('abrupt_padding', 28),
    }

    # Core 5-step pipeline
    df = process_signals(df, value_col, debug=debug)
    segments = get_segments(df)
    segments = refine_segments(df, value_col, segments, method_params)
    segments = analyse_segments(df, value_col, segments)
    if plot: plot_pytrendy(df, value_col, segments)

    results = PyTrendyResults(segments)
    return results