Skip to content

bounding_box_query slows down with string cell IDs in newest spatialdata release #1279

Description

@sophiamaedler

Report

I noticed a substantial slowdown cropping a Xenium dataset after upgrading from SpatialData 0.7.3 to 0.8.0.

bounding_box
→ _filter_table_by_elements
→ join_spatialelement_table
→ _get_joined_table_indices
→ np.isin

Execution was repeatedly inside NumPy’s object-array comparison loop (mask |= (ar1 == a)).

PR #1131 routes filtering through the shared join implementation and replaces Pandas .isin() with NumPy isin() in the membership helpers. I suspect this change is responsible for the slowdown with string IDs.

Reproduction

I’ve attached a script that runs ten bounding-box crop repeats for both numeric and string cell IDs using the public Xenium breast cancer sample xenium_rep1_io. The sample has 167,780 cells and numeric IDs; the script casts them to strings for the string-ID case.

Download and extract the dataset from within the repository root:

mkdir -p temp/xenium_data
curl -L 'https://s3.embl.de/spatialdata/spatialdata-sandbox/xenium_rep1_io_spatialdata_0.7.1.zip' \
  -o temp/xenium_data/xenium_rep1_io.zip
unzip -q temp/xenium_data/xenium_rep1_io.zip -d temp/xenium_data

Run the attached script in the spatialdata environment:
benchmark_xenium_crop.py

python temp/benchmark_xenium_crop.py

Benchmark

The benchmark uses the central 10% of each coordinate dimension and retains 199 cells. Median crop times across ten runs were:

ID type main With Pandas .isin()
Numeric 0.0082 s 0.0096 s
String 0.4126 s 0.0141 s

The string-ID case was about 29× faster with Pandas membership checks.

Expected behavior

Bounding-box cropping should filter table rows without a substantial performance regression for string cell IDs.

Versions

| Dependency        | Version     |
| ----------------- | ----------- |
| ipykernel         | 7.4.0       |
| appnope           | 1.0.0       |
| traitlets         | 5.16.1      |
| jupyter_client    | 8.10.0      |
| tornado           | 6.5.10      |
| psutil            | 7.2.2       |
| ipywidgets        | 8.1.9       |
| comm              | 0.2.3       |
| setuptools        | 84.1.0      |
| Pygments          | 2.21.0      |
| pyzmq             | 27.2.0      |
| packaging         | 26.3        |
| debugpy           | 1.8.22      |
| typing_extensions | 4.16.0      |
| six               | 1.17.0      |
| platformdirs      | 4.13.4      |
| jupyter_core      | 5.9.1       |
| session-info2     | 0.4.2       |
| msgpack           | 1.2.3       |
| ipython           | 9.17.1      |
| python-dateutil   | 2.9.0.post0 |

| Component | Info                                                                             |
| --------- | -------------------------------------------------------------------------------- |
| Python    | 3.12.0 | packaged by conda-forge | (main, Oct  3 2023, 08:36:57) [Clang 15.0.7 ] |
| OS        | macOS-26.7.1-arm64-arm-64bit                                                     |
| Updated   | 2026-10-19 22:40                                                                 |

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions