fips.Operator.from_blocks#
- classmethod Operator.from_blocks(blocks, rows=None, cols=None, name=None)[source]#
Build an operator from its blocks, each named by its row and its column block.
A pair of blocks that is not given is zero. A labeled block is placed by its labels: it may cover part of its blocks’ labels (the rest is zero), as a transport Jacobian covers the cells a footprint touched. A
Covariancemay not (seeRaises): its variances are the diagonal of the blocks’ own pairs, so each of those must cover its block’s labels.- Parameters:
blocks (
Mapping[tuple[str,str],Any]) – Each(row_block, col_block)pair mapped to its matrix, labeled or not. Labeled: a DataFrame (dense or pandas-sparse) whose index and columns are the blocks’ own labels (noblocklevel); a tuple(matrix, row_labels, col_labels)of an array or a SciPy sparse matrix and two pandas Indexes; or anOperatoron a row space of the one blockrow_blockand a column space of the one blockcol_block. Unlabeled: an array, a SciPy sparse matrix or a form offips.linalg, whose rows and columns are in the order of the blocks’ labels in rows and cols. An array or a sparse matrix is copied, as forOperator.rows (
Space|None) – The labels of the rows and columns. By default each block’s labels are those of the labeled matrices in its row or column, which must then have the same labels (in any order); a matrix that covers part of a block is placed by giving the block’s labels here. An unlabeled matrix needs its blocks’ labels from here or from a labeled matrix in the same row or column block.cols (
Space|None) – The labels of the rows and columns. By default each block’s labels are those of the labeled matrices in its row or column, which must then have the same labels (in any order); a matrix that covers part of a block is placed by giving the block’s labels here. An unlabeled matrix needs its blocks’ labels from here or from a labeled matrix in the same row or column block.
- Returns:
The assembled matrix: sparse if every block is sparse (or diagonal), dense otherwise. A labeled block keeps its form when it covers its blocks’ labels (a pandas-sparse frame is sparse); a single block that covers both spaces keeps its form.
- Return type:
- Raises:
ValueError – If a pair is given twice, a block’s labels are found nowhere, two labeled matrices of a block have different labels and rows or cols does not give them, a labeled matrix has a label its block does not have (the message names it), a labeled matrix is on other blocks than its key names, or an unlabeled matrix has the wrong shape. For a
Covariancealso: a block has no pair of its own (("flux", "flux")), or that pair lacks a label of the block on its rows or its columns. That label would get a variance of 0, so the message names it; give the pair a row and a column for every label.
Examples
>>> import numpy as np >>> import pandas as pd >>> from fips import Operator, Space >>> obs = pd.Index(["o1", "o2"], name="obs_id") >>> H = Operator.from_blocks( ... { ... ("co2", "flux"): pd.DataFrame( ... [[1.0, 0.5], [0.0, 2.0]], ... index=obs, ... columns=pd.Index(["a", "b"], name="cell"), ... ), ... ("co2", "bias"): pd.DataFrame( ... 1.0, index=obs, columns=pd.Index(["A"], name="site") ... ), ... } ... ) >>> H.cols Space(flux: 2 x ['cell'], bias: 1 x ['site']) >>> H.dense() array([[1. , 0.5, 1. ], [0. , 2. , 1. ]])
A Jacobian of the cells a footprint touched, placed on every cell:
>>> cells = Space({"flux": pd.Index(["a", "b", "c"], name="cell")}) >>> J = pd.DataFrame( ... [[0.5], [0.2]], index=obs, columns=pd.Index(["c"], name="cell") ... ) >>> Operator.from_blocks({("co2", "flux"): J}, cols=cells).dense() array([[0. , 0. , 0.5], [0. , 0. , 0.2]])