# ferray-ma
NumPy `numpy.ma`-style masked arrays with mask propagation for the ferray workspace.
Part of the [ferray](../README.md) workspace.
## Overview
`ferray-ma` implements masked arrays for ferray's Rust-native, drop-in NumPy
replacement. The core type is `MaskedArray<T, D>`, which pairs a data array
with a boolean mask (`true` = masked/invalid). Every operation respects the
mask by skipping masked elements.
- **Core type** — `MaskedArray<T, D>` built via `MaskedArray::new(data, mask)`
or `MaskedArray::from_data(data)` (no mask). Accessors: `data()`, `mask()`,
`mask_opt()`, `shape()`, `ndim()`, `size()`, `with_fill_value()`,
`set_fill_value()`; mask control via `harden_mask()` / `soften_mask()`,
`is_hard_mask()`, `set_mask()`, `set_mask_flat()`.
- **Constructors** — `masked_where`, `masked_invalid`, `masked_equal`,
`masked_not_equal`, `masked_greater`, `masked_greater_equal`, `masked_less`,
`masked_less_equal`, `masked_inside`, `masked_outside`, `fix_invalid`, plus
`extras::{masked_all, masked_all_like, masked_values}`.
- **filled / compressed** — `filled(fill)`, `filled_default()`, and
`compressed()` (unmasked elements as a 1-D array).
- **Mask-skipping reductions** (`reductions`) — `count`, `sum`, `mean`, `min`,
`max`, `var`, `var_ddof`, `std`, `std_ddof`, plus axis variants
(`sum_axis`, `mean_axis`, `min_axis`, `max_axis`, `var_axis`, `std_axis`,
`count_axis`). All-masked reductions return NaN (`mean`) or error (`min`).
- **Arithmetic** (`arithmetic`) — `masked_add`/`masked_sub`/`masked_mul`/
`masked_div` (and `_array` variants) with mask-union propagation; `&a + &b`
operator syntax is supported.
- **Ufunc support** (`ufunc_support`) — named wrappers (`sin`, `exp`, `sqrt`,
`power`, …), generic escape hatches `masked_unary` / `masked_binary`, and
domain-masking wrappers `sqrt_domain`, `log_domain`, `arcsin_domain`,
`arccos_domain`, `arctanh_domain`, `divide_domain`, … that auto-mask
out-of-domain inputs.
- **ndarray interop** (`mask_ops`, `interop`) — `getdata`, `getmask`,
`is_masked`, `count_masked`, `count_masked_axis`; `MaskAware` trait and
`ma_apply_unary` for code polymorphic over `Array` and `MaskedArray`.
- **`extras` namespace** — `average` / `average_returned`, `ma_median_axis`,
`ma_cov`, `ma_corrcoef`, `notmasked_contiguous_axis`, `notmasked_edges`,
`clump_masked`, `clump_unmasked`, set ops (`ma_unique`, `ma_in1d`,
`ma_isin`, `ma_intersect1d`, `ma_union1d`, …), fill-value protocol
(`default_fill_value_f64`, `maximum_fill_value`, `minimum_fill_value`,
`common_fill_value`), and mask builders (`make_mask`, `make_mask_none`,
`mask_or`).
## NumPy correspondence
| `np.ma.MaskedArray` | `MaskedArray<T, D>` |
| `np.ma.masked_where` | `masked_where` |
| `np.ma.masked_invalid` | `masked_invalid` |
| `np.ma.masked_equal` | `masked_equal` |
| `MaskedArray.filled` | `MaskedArray::filled` |
| `MaskedArray.compressed` | `MaskedArray::compressed` |
| `np.ma.getdata` / `np.ma.getmask` | `getdata` / `getmask` |
| `np.ma.average` | `MaskedArray::average` |
| `np.ma.median` | `ma_median_axis` |
| `np.ma.cov` / `np.ma.corrcoef` | `ma_cov` / `ma_corrcoef` |
## Feature flags
| `io` | off | Enables `io::save_masked` / `io::load_masked` for `MaskedArray` round-trip through paired `.npy` files (data + mask) via `ferray-io`. Optional so core functionality stays free of disk-I/O dependencies. |
## Example
```rust
use ferray_ma::MaskedArray;
use ferray_core::Array;
use ferray_core::dimension::Ix1;
// Build a masked array, masking out index 2.
let data = Array::<f64, Ix1>::from_vec(Ix1::new([5]), vec![1.0, 2.0, 3.0, 4.0, 5.0])?;
let mask = Array::<bool, Ix1>::from_vec(Ix1::new([5]), vec![false, false, true, false, false])?;
let ma = MaskedArray::new(data, mask)?;
// Mask-skipping mean: (1 + 2 + 4 + 5) / 4 == 3.0
let mean = ma.mean()?;
assert!((mean - 3.0).abs() < 1e-10);
// Fill masked slots, then keep only the unmasked elements.
let filled = ma.filled(0.0)?; // [1.0, 2.0, 0.0, 4.0, 5.0]
let kept = ma.compressed()?; // [1.0, 2.0, 4.0, 5.0]
# Ok::<(), ferray_core::FerrayError>(())
```
## MSRV & edition
- Edition 2024, MSRV 1.88.
- License: MIT OR Apache-2.0.