High-performance array manipulation functions for remapping, masking, renumbering, and transposing 3D labeled images and point clouds.
—
Specialized remapping functions using arrays instead of dictionaries, and component mapping for hierarchical label relationships. These functions provide high-performance alternatives for specific remapping scenarios and connectomics workflows.
Remap array using values array where the index corresponds to the label, providing faster remapping for dense label ranges.
def remap_from_array(
arr: NDArray[np.uint],
vals: NDArray[np.uint],
in_place: bool = True
) -> NDArray:
"""
Remap array using values array where index corresponds to label.
Args:
arr: Input N-dimensional numpy array
vals: Array of values to remap to
in_place: Modify input array to reduce memory consumption
Returns:
The remapped array
"""Usage Example:
import fastremap
import numpy as np
# Original array with labels 0-4
arr = np.array([0, 1, 2, 3, 4, 1, 2])
# Remapping array: index=old_label, value=new_label
vals = np.array([100, 200, 300, 400, 500]) # 0->100, 1->200, etc.
# Remap using array
remapped = fastremap.remap_from_array(arr, vals)
# Result: [100, 200, 300, 400, 500, 200, 300]
# In-place operation (default)
fastremap.remap_from_array(arr, vals, in_place=True)Remap array using separate keys and values arrays, providing flexibility for sparse remapping patterns.
def remap_from_array_kv(
arr: NDArray[np.integer],
keys: NDArray[np.integer],
vals: NDArray[np.integer],
preserve_missing_labels: bool = True,
in_place: bool = True
) -> NDArray:
"""
Remap array using separate keys and values arrays.
Args:
arr: Input N-dimensional numpy array
keys: Array of keys to remap from
vals: Array of values to remap to
preserve_missing_labels: Whether to leave unmapped values alone or throw KeyError
in_place: Modify input array to reduce memory consumption
Returns:
The remapped array
"""Usage Example:
import fastremap
import numpy as np
# Original array
arr = np.array([10, 20, 30, 40, 50, 20, 30])
# Separate key and value arrays
keys = np.array([10, 30, 50]) # Labels to remap
vals = np.array([100, 300, 500]) # New values
# Remap using key-value arrays
remapped = fastremap.remap_from_array_kv(arr, keys, vals, preserve_missing_labels=True)
# Result: [100, 20, 300, 40, 500, 20, 300]
# Labels 20 and 40 are preserved (not in keys array)
# Strict remapping (will error on missing labels)
# remapped = fastremap.remap_from_array_kv(arr, keys, vals, preserve_missing_labels=False)Generate mapping from connected components to their parent labels, useful for hierarchical segmentation analysis.
def component_map(
component_labels: ArrayLike,
parent_labels: ArrayLike
) -> Union[dict[int, int], dict[float, float]]:
"""
Generate mapping from connected components to their parent labels.
Args:
component_labels: Array containing component labels
parent_labels: Array containing parent labels
Returns:
Component to parent mapping dictionary
"""Usage Example:
import fastremap
import numpy as np
# Component labels (fine-grained segmentation)
components = np.array([1, 2, 3, 4])
# Parent labels (coarse-grained grouping)
parents = np.array([5, 5, 6, 7])
# Generate component-to-parent mapping
mapping = fastremap.component_map(components, parents)
# Result: {1: 5, 2: 5, 3: 6, 4: 7}
# Use case: mapping fine segmentation to cell types
cell_segments = np.array([101, 102, 103, 201, 202])
cell_types = np.array([1, 1, 1, 2, 2]) # Type 1 and Type 2 cells
type_mapping = fastremap.component_map(cell_segments, cell_types)
# Result: {101: 1, 102: 1, 103: 1, 201: 2, 202: 2}Generate mapping from parent labels to their constituent connected components, enabling hierarchical analysis from coarse to fine levels.
def inverse_component_map(
parent_labels: ArrayLike,
component_labels: ArrayLike
) -> Union[dict[int, list], dict[float, list]]:
"""
Generate mapping from parent labels to connected components.
Args:
parent_labels: Array containing parent labels
component_labels: Array containing component labels
Returns:
Parent to components mapping dictionary
"""Usage Example:
import fastremap
import numpy as np
# Parent labels (grouped regions)
parents = np.array([1, 2, 1, 3])
# Component labels (individual segments)
components = np.array([4, 4, 5, 6])
# Generate parent-to-components mapping
mapping = fastremap.inverse_component_map(parents, components)
# Result: {1: [4, 5], 2: [4], 3: [6]}
# Use case: finding all cell segments within tissue regions
tissue_regions = np.array([1, 1, 2, 2, 2])
cell_ids = np.array([101, 102, 201, 202, 203])
region_to_cells = fastremap.inverse_component_map(tissue_regions, cell_ids)
# Result: {1: [101, 102], 2: [201, 202, 203]}import fastremap
import numpy as np
# Common connectomics pipeline
# 1. Start with oversegmented image
overseg = np.array([1, 1, 2, 2, 3, 3, 4, 4])
# 2. Create agglomeration mapping (components to neurons)
neuron_mapping = {1: 100, 2: 100, 3: 200, 4: 300} # Merge 1,2 into neuron 100
# 3. Apply remapping
neurons = fastremap.remap(overseg, neuron_mapping)
# Result: [100, 100, 100, 100, 200, 200, 300, 300]
# 4. Generate component map for analysis
comp_map = fastremap.component_map([1, 2, 3, 4], [100, 100, 200, 300])
# Result: {1: 100, 2: 100, 3: 200, 4: 300}import fastremap
import numpy as np
# For dense, sequential labels, array-based remapping is faster
labels = np.random.randint(0, 1000, size=(1000, 1000))
remap_array = np.arange(1000) * 2 # Double each label
# Fast array-based remapping
remapped = fastremap.remap_from_array(labels, remap_array)
# Compare to dictionary-based approach (slower for dense labels)
# remap_dict = {i: i*2 for i in range(1000)}
# remapped = fastremap.remap(labels, remap_dict) # slowerArrayLike = Union[np.ndarray, list, tuple]
NDArray = np.ndarrayInstall with Tessl CLI
npx tessl i tessl/pypi-fastremap