detrend¶
MATLAB equivalent:
sidDetrend
detrend ¶
Polynomial detrending for time-domain data.
detrend ¶
detrend(x: ndarray, *, order: int = 1, segment_length: int | None = None) -> tuple[ndarray, ndarray]
Remove a polynomial trend from time-domain data.
Fits and subtracts a polynomial trend of degree order from each channel (and each trajectory) of x. Detrending is standard preprocessing before spectral estimation: unremoved trends bias low-frequency spectral estimates and violate stationarity assumptions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray, shape (N,), (N, n_ch), or (N, n_ch, L)
|
Real-valued time-domain data. A 1-D array is treated as a
single-channel column signal and the returned arrays are
squeezed back to 1-D. For multi-trajectory data, pass a 3-D
array |
required |
order
|
int
|
Polynomial degree to remove. |
1
|
segment_length
|
int
|
When set, each non-overlapping segment of this length is
detrended independently. Must be a positive integer. If
segment_length exceeds N it is silently clamped to N.
Default is |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
x_detrended |
ndarray, same shape as *x*
|
The detrended data, |
trend |
ndarray, same shape as *x*
|
The polynomial trend that was removed, so that
|
Raises:
| Type | Description |
|---|---|
SidError
|
If x is complex (code: |
SidError
|
If x contains NaN or Inf values (code: |
SidError
|
If order is not a non-negative integer
(code: |
SidError
|
If segment_length is not a positive integer
(code: |
Examples:
Remove a linear trend (the default):
>>> import numpy as np
>>> from sid.detrend import detrend
>>> t = np.arange(100, dtype=float)
>>> x = 3.0 * t + np.random.default_rng(0).standard_normal(100)
>>> x_dt, trend = detrend(x)
>>> x_dt.shape
(100,)
Remove the mean only:
Segment-wise detrending:
Multi-channel data:
Typical preprocessing workflow:
>>> import sid
>>> y_dt, _ = detrend(y)
>>> u_dt, _ = detrend(u)
>>> result = sid.freq_bt(y_dt, u_dt)
Notes
Algorithm:
- Validate inputs (real, finite, correct parameter types).
- For each trajectory and channel, split the signal into non-overlapping segments of length segment_length.
- In each segment, fit a polynomial of degree
min(order, segment_length - 1)using least-squares (numpy.polyfit) and evaluate it (numpy.polyval) to obtain the local trend. - Subtract the assembled trend from the original data.
If a segment is too short for the requested polynomial order, the order is automatically reduced and a warning is issued.
Specification: Data preprocessing -- not yet in SPEC.md.
See Also
sid.freq_bt : Blackman-Tukey spectral analysis. sid.freq_etfe : Empirical Transfer Function Estimate. sid.freq_map : Maximum a-posteriori frequency response estimation.
Changelog
2026-04-08 : First version (Python port) by Pedro Lourenco.