Repository navigation
Conversation
slice and locate check the sort order and copy the searched columns on every call, which dominates their cost when a large table is searched thousands of times. SortedFeatures sorts a table by one dimension and stores its columns as NumPy arrays once. window and window_around return the run of sorted rows within inclusive bounds, compared in float64 as slice compares them. extract aggregates the rows of each window onto a dense integer axis (max or sum), such as extracted-ion chromatograms over scans, and weighted_mean averages a column over each window.
The pandas 2.3.3 annotations accept a list of strings for a DataFrame index only through SequenceNotStr, which pyright rejects for list[str].
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
deimos.sliceanddeimos.locatecheck whether the searched column is sorted and copy the searched columns on every call. On a 27.5-million-row LC-MS centroid table, that overhead is about 135 ms per call before any row is selected, so code that searches one large table thousands of times (one extracted-ion chromatogram per target, one lookup per peak) builds sorted NumPy arrays and searches them withnp.searchsortedinstead of calling deimos.This PR adds
deimos.subset.SortedFeatures, which sorts a table by one dimension once and stores its columns as NumPy arrays. Each lookup is then a binary search plus the rows it returns.window(low, high)returns the first position and one past the last position of the sorted rows within inclusive bounds, for one window or an array of them. Bounds are compared in float64, asslicecompares them, including on float32 columns:float32(0.1)is outside[0.1, 0.1]undersliceand underwindow.window_around(loc, tol, relative)gives the same windows from locations and a tolerance, with the boundslocate_asymcomputes (x * (1 - tol)andx * (1 + tol)for a relative tolerance).extract(loc, tol, relative, along, start, stop, value, how, fill)aggregates the rows of each window onto a dense integer axis and returns an array of shape(len(loc), stop - start). Withby="mz"andalong="scan", each row is an extracted-ion chromatogram.howis"max"or"sum", and positions without rows receivefill.weighted_mean(loc, tol, relative, of, weights, along, start, stop)averages a column (defaultby) over each window, weighted by another, optionally within a range ofalong. Windows without positive total weight give NaN.A NaN in the sorted column raises
ValueError, since it has no sorted position. No existing function changes.Verification
14 new tests in
tests/test_subset.py:sliceon a float32 column at a bound just below and at the stored value.extractwithmax, withsumand a non-zerofill, with rows outside the axis range dropped, and with values below the fill undermax.extractagainst batchslicefollowed bycollapseon the example MS1 data (frames numbered by retention time).weighted_meanwith an empty window and an axis range.python -m pytest: 397 tests, 5 failing, the same 5 that fail on master in this environment (pandas 3.0.3, NumPy 2.5.2). They are intests/test_deconvolution.py, where this environment's SciPy raises_dfitpack.errorfor a spline with too few points.ruff checkandruff format --checkpass. In this environment,pyrightreports the same 10 errors indeimos/subset.pyandtests/test_subset.pyas on master, none in the new lines. CI installs pandas 2.3.3, under which pyright also checks the label arguments toDataFrame; its pyright check and its test runs on Ubuntu, macOS, and Windows pass.Equivalence on an LC-MS run (SCIEX, 27,466,493 MS1 centroids, 6,404 scans), with chromatograms within 10 ppm of 1 to 5,000 randomly drawn centroid m/z values, over all scans or scans 1,000-1,199:
extract(..., how="max")returns the same array, bit for bit, as batchslicefollowed bycollapse(keep="scan", how="max")and as a per-window NumPy loop (np.searchsortedfor the window,np.maximum.atper scan).extracton a binned retention-time axis matches the loop on 0.05-minute bins.weighted_meanmatchesnp.averageper window for 200 windows.Time per call on that run, best of 3 to 50 repeats. Building the
SortedFeaturestook 0.15 s here, on a table already in m/z order:slice+collapseSortedFeatures.extractNotes for reviewers
extractgathers the rows of every window at once and combines them withnp.maximum.atornp.bincount. With many windows over a narrow axis range it gathers rows that the range then drops, which is why it is up to 1.8 times the per-window loop in the 200-scan rows above. Undermax, cells start atfillwhen no value is below it, which is exact and avoids a separate mask; otherwise they start at-infand a mask restoresfillto positions without rows.alongmust be an integer column. A binned axis, such as retention time in fixed bins, is a column of bin numbers that the caller computes once.deimos, unlikesliceandlocate. That is easy to add if preferred.No related issue.
Quality assurance and AI policy
To maintain project quality and respect maintainer bandwidth, please confirm the following about this pull request (PR):
python -m pytestpasses locally.Status
Developer Certificate of Origin
Note to contributors: We reserve the right to close PRs without review if they appear to lack human validation or do not meet the quality standards described in our contributing guide.