API Reference
Complete API documentation for the arrayops package.
Overview
arrayops provides fast, Rust-accelerated operations for Python’s built-in array.array type, numpy.ndarray (1D arrays), and Python memoryview objects. All operations work directly with these types without requiring new types or conversions.
Security Considerations
All arrayops functions perform comprehensive input validation and use Rust’s memory safety guarantees. For detailed security information, see the Security Documentation. Key security points:
Input validation: All inputs are validated (type, typecode, properties) before processing
Memory safety: Rust’s compile-time memory safety prevents buffer overflows and use-after-free
Error handling: Errors are handled gracefully without exposing sensitive information
No unsafe patterns: All buffer access uses safe PyO3 APIs
When using arrayops with untrusted input, consider implementing size limits to prevent denial of service (DoS) attacks through resource exhaustion.
Supported Types
arrayops supports all numeric array.array typecodes, numpy.ndarray (1D, contiguous), and memoryview objects:
Type |
Code |
Description |
Size |
|---|---|---|---|
Signed integers |
|
int8 |
1 byte |
Signed integers |
|
int16 |
2 bytes |
Signed integers |
|
int32 |
4 bytes |
Signed integers |
|
int64 |
8 bytes |
Unsigned integers |
|
uint8 |
1 byte |
Unsigned integers |
|
uint16 |
2 bytes |
Unsigned integers |
|
uint32 |
4 bytes |
Unsigned integers |
|
uint64 |
8 bytes |
Floats |
|
float32 |
4 bytes |
Floats |
|
float64 |
8 bytes |
Functions
sum(arr) -> int | float
Compute the sum of all elements in an array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
int: For integer arrays (b,B,h,H,i,I,l,L)float: For float arrays (f,d)
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguous
Notes:
Empty arrays return
0(integer) or0.0(float)Integer overflow follows Python’s semantics (promotion to larger types)
Performance: ~100x faster than Python’s built-in
sum()for large arraysParallel execution: When built with
--features parallel, arrays with 10,000+ elements automatically use parallel processing for additional speedup on multi-core systemsSIMD optimization: Infrastructure available via
--features simd(full implementation pending)
Example:
import array
import arrayops as ao
# Integer array
arr = array.array('i', [1, 2, 3, 4, 5])
result = ao.sum(arr)
print(result) # 15
print(type(result)) # <class 'int'>
# Float array
farr = array.array('f', [1.5, 2.5, 3.5])
result = ao.sum(farr)
print(result) # 7.5
print(type(result)) # <class 'float'>
# Empty array
empty = array.array('i', [])
result = ao.sum(empty)
print(result) # 0
See also:
scale(arr, factor) -> None
Scale all elements of an array in-place by a factor.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type (modified in-place). Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1D and contiguousFor
memoryview: must be writable (read-only memoryviews raise ValueError)
factor(float): Scaling factor to multiply each element by
Returns:
None: This function modifies the array in-place and returns nothing
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: Ifmemoryviewis read-only
Notes:
The array is modified in-place; no new array is created
For integer arrays, the factor is cast to the array’s integer type
Empty arrays are handled gracefully (no error, array remains empty)
Performance: ~50x faster than Python loops for large arrays
Parallel execution: When built with
--features parallel, arrays with 5,000+ elements automatically use parallel processing for additional speedup on multi-core systemsSIMD optimization: Infrastructure available via
--features simd(full implementation pending)
Example:
import array
import arrayops as ao
# Integer array
arr = array.array('i', [1, 2, 3, 4, 5])
ao.scale(arr, 2.0)
print(list(arr)) # [2, 4, 6, 8, 10]
# Float array
farr = array.array('f', [1.0, 2.0, 3.0])
ao.scale(farr, 1.5)
print(list(farr)) # [1.5, 3.0, 4.5]
# Negative factor
arr = array.array('i', [1, 2, 3])
ao.scale(arr, -1.0)
print(list(arr)) # [-1, -2, -3]
# Zero factor
arr = array.array('i', [1, 2, 3])
ao.scale(arr, 0.0)
print(list(arr)) # [0, 0, 0]
See also:
map(arr, fn) -> array.array | numpy.ndarray
Apply a function to each element, returning a new array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dfn(callable): Function that takes one element and returns a value of the same type as the input array
Returns:
array.arrayornumpy.ndarray: New array with the same type as the input arrayReturns
numpy.ndarrayif input isnumpy.ndarrayReturns
array.arrayif input isarray.arrayormemoryview
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousTypeError: Iffnis not callableTypeError: If function returns a value that cannot be converted to the array’s type
Notes:
Returns a new array; the original array is not modified
The function must return a value that can be converted to the array’s element type
Empty arrays return an empty array of the same type
Performance: ~20x faster than Python list comprehensions for large arrays
Example:
import array
import arrayops as ao
# Double each element
arr = array.array('i', [1, 2, 3, 4, 5])
doubled = ao.map(arr, lambda x: x * 2)
print(list(doubled)) # [2, 4, 6, 8, 10]
# Using named function
def square(x):
return x * x
squared = ao.map(arr, square)
print(list(squared)) # [1, 4, 9, 16, 25]
# Float arrays
farr = array.array('f', [1.5, 2.5, 3.5])
halved = ao.map(farr, lambda x: x / 2.0)
print(list(halved)) # [0.75, 1.25, 1.75]
See also:
map_inplace(arr, fn) -> None
Apply a function to each element in-place.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type (modified in-place). Must be one of:b,B,h,H,i,I,l,L,f,dFor
memoryview: must be writable
fn(callable): Function that takes one element and returns a value of the same type as the input array
Returns:
None: This function modifies the array in-place and returns nothing
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousTypeError: Iffnis not callableTypeError: If function returns a value that cannot be converted to the array’s typeValueError: Ifmemoryviewis read-only
Notes:
The array is modified in-place; no new array is created
The function must return a value that can be converted to the array’s element type
Empty arrays are handled gracefully (no error, array remains empty)
Performance: ~15x faster than Python loops for large arrays
Example:
import array
import arrayops as ao
# Double each element in-place
arr = array.array('i', [1, 2, 3, 4, 5])
ao.map_inplace(arr, lambda x: x * 2)
print(list(arr)) # [2, 4, 6, 8, 10]
# Square in-place
def square(x):
return x * x
ao.map_inplace(arr, square)
print(list(arr)) # [4, 16, 36, 64, 100]
See also:
filter(arr, predicate) -> array.array | numpy.ndarray
Filter elements using a predicate function, returning a new array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dpredicate(callable): Function that takes one element and returnsbool
Returns:
array.arrayornumpy.ndarray: New array containing only elements wherepredicate(element)isTrueReturns
numpy.ndarrayif input isnumpy.ndarrayReturns
array.arrayif input isarray.arrayormemoryview
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousTypeError: Ifpredicateis not callableTypeError: If predicate doesn’t returnbool
Notes:
Returns a new array; the original array is not modified
The predicate function must return a boolean value (use
bool()explicitly if needed)Empty arrays return an empty array of the same type
Performance: ~15x faster than Python list comprehensions for large arrays
Example:
import array
import arrayops as ao
# Filter even numbers
arr = array.array('i', [1, 2, 3, 4, 5, 6])
evens = ao.filter(arr, lambda x: x % 2 == 0)
print(list(evens)) # [2, 4, 6]
# Filter values greater than threshold
large = ao.filter(arr, lambda x: x > 3)
print(list(large)) # [4, 5, 6]
# Filter with named function
def is_positive(x):
return x > 0
arr_neg = array.array('i', [-2, -1, 0, 1, 2])
positives = ao.filter(arr_neg, is_positive)
print(list(positives)) # [1, 2]
See also:
reduce(arr, fn, initial=None) -> Any
Reduce array to a single value using a binary function.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dfn(callable): Binary function that takes(accumulator, element)and returns a valueinitial(optional): Initial value for the accumulator. If not provided, uses the first element as initial value.
Returns:
Any: Result of the reduction (type depends on function and initial value)
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousTypeError: Iffnis not callableValueError: If array is empty and no initial value is provided
Notes:
If
initialis provided, reduction starts with that value and processes all elementsIf
initialis not provided, the first element is used as the initial value and processing starts from the second elementEmpty arrays require an
initialvalueThe return type can be different from the array element type (e.g., reducing to a string)
Performance: ~25x faster than Python’s
functools.reducefor large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
# Sum using reduce
total = ao.reduce(arr, lambda acc, x: acc + x)
print(total) # 15
# Product with initial value
product = ao.reduce(arr, lambda acc, x: acc * x, initial=1)
print(product) # 120
# Maximum value (no initial)
maximum = ao.reduce(arr, lambda acc, x: acc if acc > x else x)
print(maximum) # 5
# Minimum with initial
minimum = ao.reduce(arr, lambda acc, x: acc if acc < x else x, initial=100)
print(minimum) # 1
# Reduce to string (different return type)
result = ao.reduce(arr, lambda acc, x: f"{acc}+{x}", initial="0")
print(result) # "0+1+2+3+4+5"
# Empty array requires initial
empty = array.array('i', [])
total = ao.reduce(empty, lambda acc, x: acc + x, initial=0)
print(total) # 0
See also:
Statistical Operations
mean(arr) -> float
Compute the arithmetic mean (average) of all elements in an array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
float: Arithmetic mean of array elements
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is empty
Notes:
Always returns a
float, even for integer arraysEmpty arrays raise
ValueErrorPerformance: ~50x faster than computing mean in pure Python
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
avg = ao.mean(arr)
print(avg) # 3.0
float_arr = array.array('f', [1.5, 2.5, 3.5, 4.5])
avg_float = ao.mean(float_arr)
print(avg_float) # 3.0
min(arr) -> int | float
Find the minimum value in an array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
int: For integer arrays (b,B,h,H,i,I,l,L)float: For float arrays (f,d)
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is empty
Notes:
Returns type matches array element type
Empty arrays raise
ValueErrorPerformance: ~30x faster than Python’s built-in
min()for large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [5, 2, 8, 1, 9])
minimum = ao.min(arr)
print(minimum) # 1
float_arr = array.array('f', [3.5, 1.2, 7.8, 0.5])
minimum_float = ao.min(float_arr)
print(minimum_float) # 0.5
max(arr) -> int | float
Find the maximum value in an array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
int: For integer arrays (b,B,h,H,i,I,l,L)float: For float arrays (f,d)
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is empty
Notes:
Returns type matches array element type
Empty arrays raise
ValueErrorPerformance: ~30x faster than Python’s built-in
max()for large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [5, 2, 8, 1, 9])
maximum = ao.max(arr)
print(maximum) # 9
float_arr = array.array('f', [3.5, 1.2, 7.8, 0.5])
maximum_float = ao.max(float_arr)
print(maximum_float) # 7.8
std(arr) -> float
Compute the population standard deviation of array elements.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
float: Population standard deviation (sqrt of variance)
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is empty
Notes:
Uses population standard deviation:
sqrt(sum((x - mean)^2) / n)Always returns a
floatEmpty arrays raise
ValueErrorPerformance: ~40x faster than computing std in pure Python
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
std_dev = ao.std(arr)
print(std_dev) # Approximately 1.414 (sqrt of 2.0)
var(arr) -> float
Compute the population variance of array elements.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
float: Population variance
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is empty
Notes:
Uses population variance:
sum((x - mean)^2) / nAlways returns a
floatEmpty arrays raise
ValueErrorPerformance: ~40x faster than computing variance in pure Python
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
variance = ao.var(arr)
print(variance) # 2.0
median(arr) -> int | float
Find the median value in an array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
int: For integer arrays (b,B,h,H,i,I,l,L)float: For float arrays (f,d)
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is empty
Notes:
For odd-length arrays, returns the middle element
For even-length arrays, returns the lower median (element at index
(n-1)/2after sorting)Returns type matches array element type
Empty arrays raise
ValueErrorPerformance: ~20x faster than computing median in pure Python
Example:
import array
import arrayops as ao
# Odd-length array
arr1 = array.array('i', [5, 2, 8, 1, 9])
median1 = ao.median(arr1)
print(median1) # 5
# Even-length array (returns lower median)
arr2 = array.array('i', [1, 2, 5, 8])
median2 = ao.median(arr2)
print(median2) # 2
Element-wise Operations
add(arr1, arr2) -> array.array | numpy.ndarray
Element-wise addition of two arrays.
Parameters:
arr1(array.array,numpy.ndarray, ormemoryview): First input arrayarr2(array.array,numpy.ndarray, ormemoryview): Second input arrayBoth arrays must have the same length
Both arrays must have compatible numeric types
Returns:
array.arrayornumpy.ndarray: New array containing element-wise sumsReturns
numpy.ndarrayif both inputs arenumpy.ndarrayReturns
array.arrayif inputs arearray.arrayormemoryviewResult type matches input types
Raises:
TypeError: If inputs are notarray.array,numpy.ndarray, ormemoryviewTypeError: If arrays use unsupported typecodesTypeError: Ifnumpy.ndarrayinputs are not 1D or not contiguousValueError: If arrays have different lengths
Notes:
Returns a new array; input arrays are not modified
Arrays must have the same length
Performance: ~30x faster than Python loops for large arrays
Example:
import array
import arrayops as ao
arr1 = array.array('i', [1, 2, 3, 4, 5])
arr2 = array.array('i', [10, 20, 30, 40, 50])
result = ao.add(arr1, arr2)
print(list(result)) # [11, 22, 33, 44, 55]
multiply(arr1, arr2) -> array.array | numpy.ndarray
Element-wise multiplication of two arrays.
Parameters:
arr1(array.array,numpy.ndarray, ormemoryview): First input arrayarr2(array.array,numpy.ndarray, ormemoryview): Second input arrayBoth arrays must have the same length
Both arrays must have compatible numeric types
Returns:
array.arrayornumpy.ndarray: New array containing element-wise productsReturns
numpy.ndarrayif both inputs arenumpy.ndarrayReturns
array.arrayif inputs arearray.arrayormemoryviewResult type matches input types
Raises:
TypeError: If inputs are notarray.array,numpy.ndarray, ormemoryviewTypeError: If arrays use unsupported typecodesTypeError: Ifnumpy.ndarrayinputs are not 1D or not contiguousValueError: If arrays have different lengths
Notes:
Returns a new array; input arrays are not modified
Arrays must have the same length
Performance: ~30x faster than Python loops for large arrays
Example:
import array
import arrayops as ao
arr1 = array.array('i', [1, 2, 3, 4, 5])
arr2 = array.array('i', [2, 3, 4, 5, 6])
result = ao.multiply(arr1, arr2)
print(list(result)) # [2, 6, 12, 20, 30]
clip(arr, min_val, max_val) -> None
Clip array elements to be within the specified range [min_val, max_val] in-place.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: must be writable (in-place operations require writable memoryview)
min_val(float): Minimum value (elements below this are set to min_val)max_val(float): Maximum value (elements above this are set to max_val)
Returns:
None: Array is modified in-place
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: Ifmemoryviewis read-only (in-place operations require writable memoryview)
Notes:
Modifies the array in-place
Elements less than
min_valare set tomin_valElements greater than
max_valare set tomax_valElements within the range are unchanged
Performance: ~25x faster than Python loops for large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 5, 10, 15, 20])
ao.clip(arr, 5.0, 15.0)
print(list(arr)) # [5, 5, 10, 15, 15]
normalize(arr) -> None
Normalize array elements to the range [0, 1] in-place using min-max normalization.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: must be writable (in-place operations require writable memoryview)Array must not be empty
Array must not have all identical values (min != max)
Returns:
None: Array is modified in-place
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: If array is emptyValueError: If all array elements are identical (min == max, division by zero)ValueError: Ifmemoryviewis read-only (in-place operations require writable memoryview)
Notes:
Modifies the array in-place
Formula:
(x - min) / (max - min)Normalizes all elements to the range [0, 1]
Requires that min != max (all elements cannot be identical)
Performance: ~25x faster than computing normalization in pure Python
Example:
import array
import arrayops as ao
arr = array.array('f', [10.0, 20.0, 30.0, 40.0, 50.0])
ao.normalize(arr)
print(list(arr)) # [0.0, 0.25, 0.5, 0.75, 1.0]
Array Manipulation
reverse(arr) -> None
Reverse the order of array elements in-place.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: must be writable (in-place operations require writable memoryview)
Returns:
None: Array is modified in-place
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: Ifmemoryviewis read-only (in-place operations require writable memoryview)
Notes:
Modifies the array in-place
Empty arrays are handled gracefully (no-op)
Performance: ~30x faster than Python’s
arr.reverse()for large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
ao.reverse(arr)
print(list(arr)) # [5, 4, 3, 2, 1]
sort(arr) -> None
Sort array elements in ascending order in-place.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: must be writable (in-place operations require writable memoryview)
Returns:
None: Array is modified in-place
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguousValueError: Ifmemoryviewis read-only (in-place operations require writable memoryview)
Notes:
Modifies the array in-place
Uses stable sort (ascending order)
Empty arrays are handled gracefully (no-op)
Performance: ~10x faster than Python’s
arr.sort()for large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [5, 2, 8, 1, 9])
ao.sort(arr)
print(list(arr)) # [1, 2, 5, 8, 9]
unique(arr) -> array.array | numpy.ndarray
Return a new array containing unique elements from the input array, sorted in ascending order.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguous (C_CONTIGUOUS or F_CONTIGUOUS)For
memoryview: read-only or writable memoryview objects are supported
Returns:
array.arrayornumpy.ndarray: New array containing unique elements in sorted orderReturns
numpy.ndarrayif input isnumpy.ndarrayReturns
array.arrayif input isarray.arrayormemoryviewResult type matches input type
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeTypeError: Ifnumpy.ndarrayis not 1D or not contiguous
Notes:
Returns a new array; the original array is not modified
Result contains unique elements in sorted (ascending) order
Empty arrays return an empty array of the same type
Performance: ~20x faster than Python’s
list(set(arr))for large arrays
Example:
import array
import arrayops as ao
arr = array.array('i', [5, 2, 8, 2, 1, 5, 9])
unique_arr = ao.unique(arr)
print(list(unique_arr)) # [1, 2, 5, 8, 9]
Error Handling
All functions provide clear, descriptive error messages:
import array
import arrayops as ao
# Wrong type
try:
ao.sum([1, 2, 3]) # TypeError: Expected array.array
except TypeError as e:
print(e)
# Unsupported typecode
try:
arr = array.array('c', b'abc') # Character array
ao.sum(arr) # TypeError: Unsupported typecode: 'c'
except TypeError as e:
print(e)
# Non-callable function
try:
arr = array.array('i', [1, 2, 3])
ao.map(arr, "not a function") # TypeError: Expected callable
except TypeError as e:
print(e)
# Empty array with reduce (no initial)
try:
empty = array.array('i', [])
ao.reduce(empty, lambda acc, x: acc + x) # ValueError: reduce() of empty array
except ValueError as e:
print(e)
Type Safety
All functions validate their inputs:
Type checking ensures only
array.array,numpy.ndarray(1D, contiguous),memoryview, or Apache Arrow buffers/arrays are acceptedTypecode validation ensures only numeric types are supported
Clear error messages guide users to correct usage
For static type checking with mypy, type stubs are provided in ao._arrayops.
NumPy Integration
arrayops supports numpy.ndarray objects with the following requirements:
Arrays must be 1-dimensional (
ndim == 1)Arrays must be contiguous (either
C_CONTIGUOUSorF_CONTIGUOUS)All numeric dtypes are supported (int8/16/32/64, uint8/16/32/64, float32/64)
NumPy is an optional dependency - the package works without NumPy installed
When NumPy arrays are used with map or filter, the result is also a numpy.ndarray with the same dtype as the input.
Memoryview Support
arrayops supports Python’s built-in memoryview objects:
Works with both read-only and writable memoryviews
In-place operations (
scale,map_inplace) require writable memoryviewsAll numeric format types are supported
mapandfilteroperations returnarray.array(memoryviews are read-only views)
This enables interoperability with binary data, network protocols, and other buffer-like objects.
Performance Characteristics
Operation |
Python |
arrayops |
Speedup |
|---|---|---|---|
Sum (1M ints) |
~50ms |
~0.5ms |
100x |
Scale (1M ints) |
~80ms |
~1.5ms |
50x |
Map (1M ints) |
~100ms |
~5ms |
20x |
Filter (1M ints) |
~120ms |
~8ms |
15x |
Reduce (1M ints) |
~150ms |
~6ms |
25x |
Memory overhead |
N/A |
Zero-copy |
— |
See the Performance Guide for detailed benchmarking and optimization tips.
Zero-Copy Operations
All operations use Python’s buffer protocol for zero-copy access:
No data copying between Python and Rust
Direct memory access to array data
Memory-safe operations guaranteed by Rust
slice(arr, start=None, end=None) -> memoryview
Create a zero-copy slice view of an array.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type. Must be one of:b,B,h,H,i,I,l,L,f,dFor
numpy.ndarray: must be 1-dimensional and contiguousFor
memoryview: read-only or writable memoryviews are supported
start(int, optional): Start index (default: 0)end(int, optional): End index (default: length of array)
Returns:
memoryview: A zero-copy view of the specified slice. The view shares memory with the original array, so modifications to the original array will be reflected in the view.
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryviewTypeError: If array uses an unsupported typecodeValueError: If slice indices are invalid (start > end, start > length, end > length)
Notes:
Returns a
memoryviewobject, not a new arrayZero-copy operation - no data is duplicated
Modifying the original array will affect the view
Empty slices return an empty memoryview
Example:
import array
import arrayops as ao
# Basic slicing
arr = array.array('i', [1, 2, 3, 4, 5])
view = ao.slice(arr, 1, 4)
print(list(view)) # [2, 3, 4]
print(type(view)) # <class 'memoryview'>
# Slice with defaults
view1 = ao.slice(arr, None, 3) # [1, 2, 3]
view2 = ao.slice(arr, 2, None) # [3, 4, 5]
view3 = ao.slice(arr, None, None) # [1, 2, 3, 4, 5]
# Zero-copy: modifications to original affect view
arr[2] = 99
print(list(view)) # [2, 99, 4] (view reflects the change)
See also:
array_iterator(arr) -> ArrayIterator
Create an efficient Rust-optimized iterator for an array-like object.
Parameters:
arr(array.array,numpy.ndarray,memoryview, or Arrow buffer/array): Input array with numeric type
Returns:
ArrayIterator: An iterator object that supports Python’s iterator protocol
Raises:
TypeError: If input is not anarray.array,numpy.ndarray,memoryview, or Arrow buffer/arrayTypeError: If array uses an unsupported typecode
Notes:
The iterator uses Rust’s buffer protocol for efficient element access
Works with all supported array types (array.array, numpy.ndarray, memoryview)
Compatible with Python’s iterator protocol (for loops, list(), sum(), etc.)
Zero-copy or near-zero-copy iteration from Rust buffers
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
# Create iterator
it = ao.array_iterator(arr)
# Use in for loop
for value in it:
print(value) # Prints: 1, 2, 3, 4, 5
# Convert to list
it = ao.array_iterator(arr)
values = list(it)
print(values) # [1, 2, 3, 4, 5]
# Use with built-in functions
it = ao.array_iterator(arr)
total = sum(it)
print(total) # 15
See also:
ArrayIterator Class
An efficient Rust-optimized iterator for array-like objects.
The ArrayIterator class provides efficient iteration over array types using Rust’s buffer protocol access. It implements Python’s iterator protocol and can be used in for loops, list comprehensions, and other iterator contexts.
Constructor
ArrayIterator(source)
Create a new ArrayIterator from a source array.
source(array.array,numpy.ndarray,memoryview, or Arrow buffer/array): The source array to iterate overReturns: New
ArrayIteratorinstance
Methods
__iter__() -> ArrayIterator
Return the iterator itself (required by iterator protocol).
Returns: The iterator object itself
__next__() -> Union[int, float]
Return the next element in the iteration.
Returns: The next element in the array (int for integer arrays, float for float arrays)
Raises:
StopIterationwhen there are no more elements
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
# Create iterator
it = ao.array_iterator(arr)
# Use iterator protocol methods
it2 = iter(it) # __iter__() called
first = next(it2) # 1 (__next__() called)
second = next(it2) # 2
third = next(it2) # 3
# Use in for loop
for value in ao.array_iterator(arr):
print(value) # Prints: 1, 2, 3, 4, 5
See also:
lazy_array(arr) -> LazyArray
Create a lazy array that can chain operations without intermediate allocations.
Parameters:
arr(array.array,numpy.ndarray, ormemoryview): Input array with numeric type
Returns:
LazyArray: A lazy array object that supports chaining operations
Raises:
TypeError: If input is not anarray.array,numpy.ndarray, ormemoryview
Notes:
Lazy arrays defer execution until
collect()is calledOperations can be chained:
lazy.map(fn).filter(pred).collect()More memory-efficient than multiple separate
map()andfilter()callsResult is cached after first
collect()call
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
# Create lazy array and chain operations
lazy = ao.lazy_array(arr)
result = lazy.map(lambda x: x * 2).filter(lambda x: x > 5).collect()
print(list(result)) # [6, 8, 10]
# Multiple map operations
lazy = ao.lazy_array(arr)
result = lazy.map(lambda x: x * 2).map(lambda x: x + 1).collect()
print(list(result)) # [3, 5, 7, 9, 11]
See also:
LazyArray Class
A lazy array wrapper that chains operations without intermediate allocations.
Methods
map(function) -> LazyArray
Apply a function to each element (returns a new LazyArray, does not execute).
function(callable): Function to apply to each elementReturns: New
LazyArraywith the map operation added to the chain
filter(predicate) -> LazyArray
Filter elements based on a predicate (returns a new LazyArray, does not execute).
predicate(callable): Predicate function that returns True/FalseReturns: New
LazyArraywith the filter operation added to the chain
collect() -> array.array | numpy.ndarray
Execute all chained operations and return the result.
Returns: Result array (same type as input:
array.arrayornumpy.ndarray)
source() -> array.array | numpy.ndarray
Get the source array.
Returns: Original source array
len() -> int
Get the number of operations in the chain.
Returns: Number of operations in the chain
__iter__() -> ArrayIterator
Iterator protocol: evaluate lazy chain and return an iterator.
Returns: An
ArrayIteratorover the evaluated array resultNotes: This method evaluates the lazy chain (if not already cached) and returns an iterator over the result, enabling direct iteration over LazyArray objects
Example:
import array
import arrayops as ao
arr = array.array('i', [1, 2, 3, 4, 5])
lazy = ao.lazy_array(arr)
# Chain multiple operations
lazy = lazy.map(lambda x: x * 2)
lazy = lazy.filter(lambda x: x > 5)
# Check chain length
print(lazy.len()) # 2
# Execute and get result
result = lazy.collect()
print(list(result)) # [6, 8, 10]
# Get source
source = lazy.source()
print(list(source)) # [1, 2, 3, 4, 5]
# Iterate directly (evaluates chain automatically)
lazy = ao.lazy_array(arr)
lazy = lazy.map(lambda x: x * 2).filter(lambda x: x > 5)
for value in lazy:
print(value) # Prints: 6, 8, 10
Arrow Buffer Support
arrayops supports Apache Arrow buffers and arrays (pyarrow.Buffer, pyarrow.Array, pyarrow.ChunkedArray):
All operations work transparently with Arrow arrays
Arrow arrays are detected automatically
Results are returned as Arrow arrays when Arrow input is used
Requires
pyarrowto be installed (optional dependency)