GH-33295: [C++][Python] Add list_contains compute function - #51611
Open
jonasdedden wants to merge 12 commits into
Open
jonasdedden wants to merge 12 commits into
jonasdedden wants to merge 12 commits into
Conversation
jonasdedden
requested review from
AlenkaF,
pitrou,
raulcd and
rok
as code owners
September 28, 2026 18:07
This was referenced Sep 28, 2026
…ews in list_contains
…es in list_contains
Contributor
Author
|
@pitrou @zanmato1984 and/or @AlenkaF |
Contributor
Author
|
972bc4c speeds up the per-list scan: short lists are now 2.4-4.1x faster, long lists are unchanged. The scan used to build an
Setup and script50M """Time pc.list_contains against the `equal` pass it is built on. Run once per build."""
import json
import sys
import time
import numpy as np
import pyarrow as pa
import pyarrow.compute as pc
N_VALUES = 50_000_000
CASES = [(1, 1e-5), (3, 1e-5), (3, 0.3), (10, 0.3), (100, 0.3), (1000, 1e-5), (1000, 0.3)]
def best_ms(func, repeats=7):
times = []
for _ in range(repeats):
start = time.perf_counter()
func()
times.append(time.perf_counter() - start)
return min(times) * 1e3
results = {}
for list_length, match_rate in CASES:
rng = np.random.default_rng(42)
values = rng.integers(2, 1 << 40, N_VALUES)
values[rng.random(N_VALUES) < match_rate] = 1
offsets = np.arange(0, N_VALUES + 1, list_length, dtype=np.int32)
lists = pa.ListArray.from_arrays(offsets, pa.array(values))
flat = lists.values
item = pa.scalar(1, pa.int64())
results[f"{list_length},{match_rate}"] = {
"list_contains": best_ms(lambda: pc.list_contains(lists, item)),
"equal": best_ms(lambda: pc.equal(flat, item)),
}
json.dump(results, sys.stdout) |
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.
Rationale for this change
There is no direct way to check whether each list in a list array contains a value. This PR closes #33295.
What changes are included in this PR?
A binary scalar function
list_contains(lists, value)returning a boolean per list, for list, large list, list view, large list view and fixed-size list inputs.valuecan be a scalar, or an array of the same length, in which case each list is searched for the value at the same index. A scalarlistspaired with an array of values is broadcast.Each list type provides its child values in list order (a slice for lists and fixed-size lists,
Flatten()for list views), so each list's range follows the previous one. These values are compared once withequal, so implicit casts apply (e.g. an int8 list and an int64 value). For an array of values, each value is first repeated for its list's child values withtake, and compared element-wise with the same semantics. Each list's range in the resulting bitmap is then scanned, stopping at the first match.Semantics:
is_inand Polars (equalsays NaN != NaN).Are these changes tested?
Yes, in
scalar_nested_test.ccandtest_compute.py. Cases include sliced, chunked and out-of-order list-view inputs, arrays of values, scalar lists with arrays of values, lists spanning several bitmap words, null and NaN values (including float16), implicit casts, several value types, and type errors for null values.Are there any user-facing changes?
Yes, a new compute function,
pyarrow.compute.list_containsin Python.Was AI used for this PR?
PR code and description written by:
Reviewed before submission by: