DesignMatrix ¶
DesignMatrix(
data: DesignMatrix
| DataFrame
| DataFrame
| ndarray
| dict
| str
| Path
| None = None,
*,
sampling_freq: float | None = None,
TR: float | None = None,
run_length: int | str | None = None,
columns: list[str] | None = None,
convolved: list[str] | None = None,
confounds: list[str] | None = None,
hrf_model: str | None = "glover",
n_rows: int | None = None,
)
Represent an experimental design for neuroimaging as a Polars-backed matrix.
Wraps a Polars DataFrame (one row per timepoint, one column per regressor)
together with the metadata a GLM needs: the sampling frequency, which
columns have been HRF-convolved, and which columns are nuisance/confound
regressors. Transformations return new instances with that metadata
preserved; DesignMatrix is composed over the DataFrame rather than
subclassing it. Unknown attributes are forwarded to the underlying
DataFrame, so the Polars API is available directly (dm.select(...),
dm.filter(...), dm.slice(...) return a DesignMatrix). Every eager DataFrame result becomes a new
DesignMatrix; Series and builder objects remain native Polars values.
Metadata is retained only when the operation establishes its validity.
data accepts a Polars DataFrame (copied), a pandas DataFrame
(converted), a NumPy array (named via columns), a dict of columns,
another DesignMatrix (copied), None (empty), or a file path.
A .tsv/.csv path is read as a BIDS events file when it has onset
and duration columns — each trial_type becomes an HRF-convolved
regressor, or a raw boxcar under hrf_model=None — and as a plain table
otherwise (typically confounds). A .h5/.hdf5 path written by write restores
the data and the metadata (sampling_freq, convolved, confounds,
multi), so neither run_length nor sampling_freq is required;
passing either overrides what the file recorded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DesignMatrix | DataFrame | DataFrame | ndarray | dict | str | Path | None
|
Input data; see above for how each type is interpreted. |
None
|
sampling_freq
|
float | None
|
Sampling frequency in Hz (1/TR for fMRI
data). Mutually exclusive with |
None
|
TR
|
float | None
|
Repetition time in seconds, a convenience for
|
None
|
run_length
|
int | str | None
|
Number of TRs in the run. Required when
|
None
|
columns
|
list[str] | None
|
Column names, used with NumPy input. |
None
|
convolved
|
list[str] | None
|
Names of columns that are already HRF-convolved. |
None
|
confounds
|
list[str] | None
|
Names of nuisance/confound columns (intercept, polynomial drift, DCT cosines, motion, …). |
None
|
hrf_model
|
str | None
|
HRF model used to convolve regressors loaded
from a BIDS events file — |
'glover'
|
n_rows
|
int | None
|
Number of timepoints for a matrix with no columns
(Polars cannot represent "n rows, 0 columns"). Rarely needed
directly; set by |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
data |
DataFrame
|
The underlying Polars DataFrame. |
sampling_freq |
float | None
|
Sampling frequency in Hz. |
convolved |
list[str]
|
Names of HRF-convolved columns (read-only;
managed by |
confounds |
list[str]
|
Names of nuisance/confound columns (read-only;
managed by |
multi |
bool
|
True if the matrix was created by a multi-run
vertical |
columns |
list[str]
|
Column names. |
shape |
tuple[int, int]
|
|
is_empty |
bool
|
True if the matrix holds no data. |
Examples:
# Create from a NumPy array
dm = DesignMatrix(np.zeros((100, 2)), sampling_freq=0.5, columns=["a", "b"])
# Add a column
dm["stim"] = [0, 1, 1, 0] * 25
# Convolve with the HRF — convolved columns get a `_c0` suffix
dm_conv = dm.convolve() # 'stim' → 'stim_c0'
# Add polynomial drift terms
dm_conv = dm_conv.add_poly(order=2)
# Multi-run concatenation separates drift terms per run
dm_run1 = DesignMatrix(run1_events, sampling_freq=0.5, run_length=100).add_poly(0)
dm_run2 = DesignMatrix(run2_events, sampling_freq=0.5, run_length=100).add_poly(0)
dm_multi = dm_run1.append(dm_run2, axis=0) # → .nl_r0_poly_0, .nl_r1_poly_0
Passing another DesignMatrix returns a copy: data, sampling_freq,
convolved, confounds, and multi are carried over, and any explicit
kwarg overrides the inherited value.
When data is a path to a BIDS events file, the events go to nilearn's
make_first_level_design_matrix with the named hrf_model
('glover' by default): output columns are suffixed _c0 and
convolved is populated. Pass hrf_model=None to load raw boxcar
regressors instead — useful for FIR designs, PPI flows that build
interaction terms before convolution, or teaching material that
introduces convolution as a separate step. Those boxcars are sampled
onto the TR grid, so convolving them afterwards with convolve is not
the same as letting the constructor convolve the events: onsets that
fall between TRs have already been quantized.
Methods:
| Name | Description |
|---|---|
add_dct_basis |
Add discrete cosine transform basis functions for high-pass filtering. |
add_poly |
Add Legendre polynomial drift terms. |
append |
Concatenate design matrices. |
clean |
Remove highly correlated columns. |
convolve |
Convolve columns with an HRF model or custom kernel. |
copy |
Create a deep copy of the DesignMatrix. |
corr |
Calculate column correlations as a similarity |
downsample |
Reduce temporal resolution using Polars-native operations. |
drop |
Drop specified columns. |
fillna |
Fill NaN/null values with specified value. |
plot |
Visualize the design matrix. |
replace_data |
Replace data columns while preserving confounds and metadata. |
standardize |
Standardize columns by centering them, optionally scaling to unit variance. |
sum |
Compute the sum along an axis. |
to_numpy |
Convert a DesignMatrix to a NumPy array. |
upsample |
Increase temporal resolution to a target frequency. |
vif |
Compute the variance inflation factor for each column. |
with_columns |
Add or replace columns via Polars expressions. |
write |
Write DesignMatrix to file. |
Attributes¶
columns
property
writable
¶
Column names of the design matrix as a list of strings.
confounds
property
writable
¶
Names of nuisance/confound columns (read-only).
Managed by convolve, append, add_poly, add_dct_basis, and the
confounds= constructor kwarg. Direct assignment raises
AttributeError — pass via the constructor or use
.append(other, axis=1) (which auto-tracks confounds when other
is a raw Polars DataFrame).
convolved
property
writable
¶
Names of HRF-convolved columns (read-only).
Managed by convolve and append (which merges across inputs).
Direct assignment raises AttributeError — pass via the
convolved= constructor kwarg if you need to set initial state.
shape
property
¶
shape: tuple
The (n_rows, n_cols) shape of the matrix.
For a matrix with no regressors, n_rows comes from the height
recorded at construction (Polars cannot represent "n rows, 0 columns").
Methods:¶
add_dct_basis ¶
add_dct_basis(
duration: float = 180,
drop: int = 0,
*,
include_constant: bool = True,
) -> DesignMatrix
Add discrete cosine transform basis functions for high-pass filtering.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
duration
|
float
|
Filter duration in seconds. Default: 180. |
180
|
drop
|
int
|
Number of low-frequency bases to drop. Default: 0. |
0
|
include_constant
|
bool
|
If True, also add a constant/intercept
column named |
True
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with DCT basis columns appended. |
add_poly ¶
add_poly(
order: int = 0, include_lower: bool = True
) -> DesignMatrix
Add Legendre polynomial drift terms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
int
|
Polynomial order (0=intercept, 1=linear, 2=quadratic, ...). Default: 0. |
0
|
include_lower
|
bool
|
If True, include all orders from 0 to order. Default: True. |
True
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with polynomial columns appended. |
append ¶
append(
data: DesignMatrix | list[DesignMatrix],
*,
axis: int = 0,
keep_separate: bool = True,
unique_cols: list[str] | None = None,
fill_na: int | float | None = 0,
as_confounds: bool = False,
progress_bar: bool = False,
) -> DesignMatrix
Concatenate design matrices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DesignMatrix or list of DesignMatrix
|
Design matrix/matrices to append. |
required |
axis
|
int
|
0 for row-wise (vertical), 1 for column-wise (horizontal). Default: 0. |
0
|
keep_separate
|
bool
|
Whether to separate confound columns across runs (only applies when axis=0). Default: True. |
True
|
unique_cols
|
list of str
|
Additional columns to keep separated (supports wildcards). |
None
|
fill_na
|
int, float, or None
|
Value to fill NaN values during vertical concatenation, or None to preserve nulls. Default: 0. |
0
|
as_confounds
|
bool
|
Only applies when |
False
|
progress_bar
|
bool
|
Print messages about confound separation. Default: False. |
False
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
Concatenated design matrix. |
clean ¶
clean(
*,
fill_na: int | float | None = 0,
exclude_confounds: bool = False,
thresh: float = 0.95,
progress_bar: bool = False,
) -> DesignMatrix
Remove highly correlated columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fill_na
|
int, float, or None
|
Fill NaN values before checking correlations (default 0) |
0
|
exclude_confounds
|
bool
|
Skip confound/nuisance columns from correlation check |
False
|
thresh
|
float
|
Correlation threshold (drop if abs® >= thresh, default 0.95) |
0.95
|
progress_bar
|
bool
|
Print dropped column names. Default: False |
False
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
Cleaned matrix with highly correlated columns removed |
convolve ¶
convolve(
kernel: str | ndarray = "glover",
columns: list[str] | None = None,
) -> DesignMatrix
Convolve columns with an HRF model or custom kernel.
Convolved columns are always renamed to <col>_c{i} (where i is
the kernel index, 0 for a single 1-D kernel). The source columns
are dropped, and self.convolved lists the post-suffix names so
downstream metadata stays in sync with the dataframe.
A kernel name selects one of nilearn's HRF models: each column goes to
nilearn.glm.first_level.compute_regressor as a condition, convolved
at an oversampling factor of 50 and resampled onto the frame times.
That is exactly what FirstLevelModel computes, so a column whose
samples sit on the TR grid gives the regressor nilearn would build from
the same events; sub-TR timing a column cannot represent is lost before
convolution, so pass an events table to the constructor for that.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kernel
|
str or ndarray
|
An HRF model name — |
'glover'
|
columns
|
list of str
|
Columns to convolve (default: all non-confound columns). |
None
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with convolved columns renamed. |
copy ¶
copy() -> DesignMatrix
Create a deep copy of the DesignMatrix.
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
Copy of the current DesignMatrix |
corr ¶
Calculate column correlations as a similarity Adjacency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metric
|
str
|
|
'pearson'
|
columns
|
list of str
|
Subset of columns to correlate. Defaults to all columns. |
None
|
Returns:
| Type | Description |
|---|---|
Adjacency
|
Similarity matrix whose |
downsample ¶
downsample(
target: float, method: str = "mean"
) -> DesignMatrix
Reduce temporal resolution using Polars-native operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
float
|
Target sampling frequency in Hz (must be < current sampling_freq) |
required |
method
|
str
|
Aggregation method - 'mean' or 'median' (default: 'mean') |
'mean'
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
Downsampled DesignMatrix with updated sampling_freq |
drop ¶
drop(columns: list[str]) -> DesignMatrix
Drop specified columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
columns
|
list of str
|
Column names to remove. |
required |
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix without the specified columns. |
fillna ¶
fillna(value: int | float) -> DesignMatrix
Fill NaN/null values with specified value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
int or float
|
Value to replace NaN/null entries with. |
required |
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with NaN/null values replaced. |
plot ¶
plot(
method: str = "matrix",
*,
columns: list[str] | None = None,
rescale: bool = True,
metric: str = "pearson",
ax=None,
figsize: tuple | None = None,
title: str | None = None,
cmap: str | None = None,
save: str | None = None,
**kwargs,
) -> Figure
Visualize the design matrix.
Dispatches over method (mirroring BrainData.plot):
'matrix'(default): SPM-style heatmap (rows = TRs, columns = regressors).'timeseries': overlaid line plot of regressor time courses. Pass the sameaxacross calls to overlay multiple DesignMatrices (e.g. original vs. convolved).'corr': labeled correlation heatmap of the columns (reusescorr; diagonal restored to 1.0 for display).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
One of |
'matrix'
|
columns
|
list of str
|
Subset of columns to plot. Defaults to all columns. |
None
|
rescale
|
bool
|
|
True
|
metric
|
str
|
|
'pearson'
|
ax
|
Axes
|
Existing axis to draw on; a new figure is created if omitted. |
None
|
figsize
|
tuple
|
Figure size; sensible per-method default when omitted. |
None
|
title
|
str
|
Axis title. |
None
|
cmap
|
str
|
Colormap ( |
None
|
save
|
str
|
Path to save the figure. |
None
|
**kwargs
|
dict
|
Forwarded to the underlying plotter
( |
{}
|
Returns:
| Type | Description |
|---|---|
Figure
|
The figure containing the plot. |
replace_data ¶
replace_data(
data: ndarray, column_names: list[str] | None = None
) -> DesignMatrix
Replace data columns while preserving confounds and metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
ndarray
|
New data array (must match number of rows in current DesignMatrix) |
required |
column_names
|
list of str
|
Names for new data columns. |
None
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with replaced data columns, preserved confounds |
Raises:
| Type | Description |
|---|---|
ValueError
|
If row count doesn't match existing data |
standardize ¶
standardize(
*,
method: str = "center",
columns: list[str] | None = None,
) -> DesignMatrix
Standardize columns by centering them, optionally scaling to unit variance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
|
'center'
|
columns
|
list[str] | None
|
Columns to standardize. If None, standardize all non-confound columns. |
None
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with standardized columns. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
sum ¶
sum(axis: int = 0) -> Series
Compute the sum along an axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
int
|
0 to sum down each column, 1 to sum across each row. Default: 0. |
0
|
Returns:
| Type | Description |
|---|---|
Series
|
Sums along the specified axis. |
to_numpy ¶
to_numpy() -> ndarray
Convert a DesignMatrix to a NumPy array.
Returns:
| Type | Description |
|---|---|
ndarray
|
2D array with shape (n_samples, n_columns) |
upsample ¶
upsample(
target: float, method: str = "linear"
) -> DesignMatrix
Increase temporal resolution to a target frequency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
float
|
Target sampling frequency in Hz (must be > current sampling_freq) |
required |
method
|
str
|
Interpolation method - 'linear' or 'nearest' (default: 'linear') |
'linear'
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
Upsampled DesignMatrix with updated sampling_freq |
vif ¶
with_columns ¶
with_columns(*exprs, **named_exprs) -> DesignMatrix
Add or replace columns via Polars expressions.
Mirrors pl.DataFrame.with_columns. Named kwargs become named
columns; positional pl.Expr arguments are accepted as-is
(including pl.Expr.alias("name")). Returns a new DesignMatrix
preserving annotations on untouched columns. Replacing a column clears
its convolution annotation and retains its confound role; new columns
are untagged.
For convenience, named-kwarg values that aren't pl.Expr /
pl.Series are coerced: an int/float is broadcast as a
scalar via pl.lit, and a list / np.ndarray is wrapped as a
pl.Series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*exprs
|
Expr
|
Positional Polars expressions, passed through. |
()
|
**named_exprs
|
Expr | Series | ndarray | list | int | float
|
New columns keyed by name. |
{}
|
Returns:
| Type | Description |
|---|---|
DesignMatrix
|
New DesignMatrix with the columns added or replaced. |
Examples:
write ¶
Write DesignMatrix to file.
Supports TSV, CSV, and HDF5 formats. Format is auto-detected from the
file extension. Text formats carry the data only; .h5 also
preserves sampling_freq, .convolved, .confounds, and
.multi, so DesignMatrix(path) restores the whole object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Output file path with a |
required |
sep
|
str | None
|
Column separator for text files. Defaults to the
delimiter the extension implies (comma for |
None
|