Skip to content

Sorting & searching: implement partition/argpartition, lexsort, nanargmax/nanargmin, sort_complex #623

Description

@Nucs

Overview

NumSharp covers the core of NumPy's Sorting & searching category (sort, argsort, searchsorted, arg*, nonzero, ...) but is missing 6 functions: the partial-sort pair, multi-key sort, NaN-aware argmin/argmax, and complex sort. This tracks adding them.

Problem

Two of the six (partition/argpartition) require a new introselect (quickselect) kernel -- the only genuinely new algorithm here; the other four are compositions over machinery NumSharp already has. argpartition/lexsort are widely used (top-k selection, multi-column sorting) and have no workaround today.

Verified codebase state

  • Implemented (np.*): sort, argsort, searchsorted, argmax, argmin, argwhere, nonzero, flatnonzero, count_nonzero, where, extract.
  • Missing (6 below): verified absent from np.* and as NDArray methods (reflection + source grep). Note: a Char8.PyBytes.Partition (bytes-string helper) and the internal NDIter engine exist but are unrelated to np.partition.

Proposal

Add under np.*. Implement the shared introselect kernel once (drives both partition and argpartition); the rest compose existing reductions/sorts.

Task checklist (ordered by real-world usage)

  • argpartition (20,304) -- new introselect kernel (shared with partition)
  • lexsort (13,944) -- stable multi-key argsort
  • nanargmax (7,008) -- compose (NumSharp has nan-aware reductions)
  • partition (6,612) -- new introselect kernel
  • nanargmin (5,920) -- compose
  • sort_complex (1,636) -- trivial

Evidence -- GitHub usage ranking

# Function GitHub hits What it does Effort
1 np.argpartition 20,304 indices that would partition the array (introselect, kth in place) new introselect kernel (shared with partition)
2 np.lexsort 13,944 indirect stable sort on a sequence of keys (last key is primary) stable multi-key argsort
3 np.nanargmax 7,008 index of the maximum, ignoring NaN compose (NumSharp has nan-aware reductions)
4 np.partition 6,612 partial sort -- kth element in its final sorted position, sides unordered new introselect kernel
5 np.nanargmin 5,920 index of the minimum, ignoring NaN compose
6 np.sort_complex 1,636 sort a complex array by real part then imaginary part trivial

Combined usage ~ 55,424 hits. Four of six compose from existing primitives; the two partial-sorts share one new introselect kernel.

Usage = GitHub REST code-search total_count in each function's canonical call form (np.<fn>(, or np.<fn>[ for the index-expression objects). It is an approximate estimate (noisy plus/minus ~10% on large sets) and counts only the dominant np. alias. Measured 2026-07-19; treat as relative demand, not exact.

Scope / Non-goals

  • kind= accepted for API parity; introselect is the only partition strategy NumPy actually implements.
  • lexsort requires a stable argsort -- verify/extend NumSharp's argsort stability as part of this.
  • NaN semantics must match NumPy exactly (all-NaN slice -> ValueError for nanarg*).

Related issues

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

    NumPy 2.x ComplianceAligns behavior with NumPy 2.x (NEPs, breaking changes)apiPublic API surface (np.*, NDArray methods, operators)coreInternal engine: Shape, Storage, TensorEngine, iteratorsenhancementNew feature or requestmissing feature/sNumPy function not yet implemented in NumSharp

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions