Masked Arrays (ma) ================== .. currentmodule:: numpycore.ma The ``ma`` module provides support for arrays with masked (invalid) elements. Example ------- .. code-block:: python import numpycore as np # Create a masked array data = np.array([1, 2, -999, 4, 5]) mask = np.array([False, False, True, False, False]) ma = np.ma.array(data, mask=mask) # Operations ignore masked values print(ma.mean()) # 3.0 (ignoring -999) print(ma.sum()) # 12 # Mask by condition ma2 = np.ma.masked_greater(data, 3) Creating Masked Arrays ---------------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Function - Description - Example * - array(data, mask) - Create masked array - :ref:`View ` * - masked_array(data, mask) - Create masked array (alias) - :ref:`View ` * - masked_where(condition, a) - Mask where condition is True - :ref:`View ` * - masked_equal(x, value) - Mask where equal to value - :ref:`View ` * - masked_not_equal(x, value) - Mask where not equal to value - * - masked_less(x, value) - Mask where less than value - :ref:`View ` * - masked_less_equal(x, value) - Mask where less than or equal - * - masked_greater(x, value) - Mask where greater than value - :ref:`View ` * - masked_greater_equal(x, value) - Mask where greater than or equal - * - masked_inside(x, v1, v2) - Mask values inside interval - * - masked_outside(x, v1, v2) - Mask values outside interval - * - masked_invalid(a) - Mask NaN and Inf values - Masked Array Attributes ----------------------- .. list-table:: :widths: 25 75 :header-rows: 1 * - Attribute - Description * - data - Underlying data array * - mask - Boolean mask array * - fill_value - Value used for filled output * - count() - Count of unmasked elements * - compressed() - Return all unmasked data as 1-D array Operations ---------- All standard NumPy operations work with masked arrays, automatically ignoring masked elements in calculations. .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Function - Description - Example * - filled(a, fill_value) - Return array with masked values filled - * - getdata(a) - Return data of masked array - :ref:`View ` * - getmask(a) - Return mask of array - :ref:`View ` * - is_masked(x) - Check if array has masked values - :ref:`View ` * - count(a) - Count non-masked elements - * - fix_invalid(a) - Fix invalid values (NaN, Inf) - Code Examples ------------- The following examples are extracted from the test suite. .. _example-ma-creation-array-0: .. dropdown:: array (test_phase13_masked_adapters.py:259) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 249 :emphasize-lines: 11 print(f"[SKIP] ma.array not available in numpycore") return True passed = True # Test: Create masked array using array() data = test_bind.np.array([1.0, 2.0, 3.0, 4.0]) mask = test_bind.np.array([False, True, False, False]) np_ma = test_bind.np.ma.array(data, mask=mask) nc_ma = test_bind.numpycore.ma.array(data, mask=mask) if not assert_masked_arrays_equal(np_ma, nc_ma, "array: create with mask"): passed = False if passed: print(f"\n[OK] ma.array() tests passed") return passed def test_asanyarray(): """Test np.ma.asanyarray() - convert to masked array""" .. _example-ma-creation-masked_array-1: .. dropdown:: masked_array (test_masked_array_wrappers.py:30) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 20 :emphasize-lines: 11 ) # ============================================================================ # Helper Functions # ============================================================================ def create_masked_array(data, mask, dtype='float64'): """Create a numpycore MaskedArray""" np_data = test_bind.np.array(data, dtype=dtype) np_mask = test_bind.np.array(mask, dtype=bool) return test_bind.numpycore.ma.masked_array(np_data, np_mask) def assert_array_equal(result, expected, test_name, rtol=1e-10, atol=1e-10): """Assert that result matches expected""" result_arr = test_bind.np.asarray(result) expected_arr = test_bind.np.asarray(expected) if not test_bind.np.allclose(result_arr, expected_arr, rtol=rtol, atol=atol, equal_nan=True): print(f"[FAIL] {test_name}: Arrays not equal") print(f" Result: {result_arr}") print(f" Expected: {expected_arr}") .. _example-ma-creation-masked_where-2: .. dropdown:: masked_where (test_masked_arrays.py:203) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 193 :emphasize-lines: 11 print("="*80) # Test: Mask where condition array is True np_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) np_condition = np_data > 3.0 nc_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) nc_condition = nc_data > 3.0 np_masked = test_bind.np.ma.masked_where(np_condition, np_data) nc_masked = test_bind.numpycore.ma.masked_where(nc_condition, nc_data) if not assert_masked_arrays_equal(np_masked, nc_masked, "masked_where: condition > 3"): return False print(f"\n[OK] ma.masked_where() tests passed") return True # ============================================================================ # Utility Functions Tests .. _example-ma-creation-masked_equal-3: .. dropdown:: masked_equal (test_masked_arrays.py:140) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 130 :emphasize-lines: 11 """Test np.ma.masked_equal() - mask where equal to value""" print("\n" + "="*80) print("Testing ma.masked_equal()") print("="*80) # Test: Mask where values equal 2 np_data = test_bind.np.array([1.0, 2.0, 3.0, 2.0, 5.0]) nc_data = test_bind.np.array([1.0, 2.0, 3.0, 2.0, 5.0]) np_masked = test_bind.np.ma.masked_equal(np_data, 2.0) nc_masked = test_bind.numpycore.ma.masked_equal(nc_data, 2.0) if not assert_masked_arrays_equal(np_masked, nc_masked, "masked_equal: value 2.0"): return False print(f"\n[OK] ma.masked_equal() tests passed") return True def test_masked_greater(): """Test np.ma.masked_greater() - mask where greater than value""" .. _example-ma-creation-masked_less-4: .. dropdown:: masked_less (test_masked_arrays.py:180) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 170 :emphasize-lines: 11 """Test np.ma.masked_less() - mask where less than value""" print("\n" + "="*80) print("Testing ma.masked_less()") print("="*80) # Test: Mask where values < 3 np_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) nc_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) np_masked = test_bind.np.ma.masked_less(np_data, 3.0) nc_masked = test_bind.numpycore.ma.masked_less(nc_data, 3.0) if not assert_masked_arrays_equal(np_masked, nc_masked, "masked_less: < 3.0"): return False print(f"\n[OK] ma.masked_less() tests passed") return True def test_masked_where(): """Test np.ma.masked_where() - mask where condition is True""" .. _example-ma-creation-masked_greater-5: .. dropdown:: masked_greater (test_masked_arrays.py:160) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 150 :emphasize-lines: 11 """Test np.ma.masked_greater() - mask where greater than value""" print("\n" + "="*80) print("Testing ma.masked_greater()") print("="*80) # Test: Mask where values > 3 np_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) nc_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) np_masked = test_bind.np.ma.masked_greater(np_data, 3.0) nc_masked = test_bind.numpycore.ma.masked_greater(nc_data, 3.0) if not assert_masked_arrays_equal(np_masked, nc_masked, "masked_greater: > 3.0"): return False print(f"\n[OK] ma.masked_greater() tests passed") return True def test_masked_less(): """Test np.ma.masked_less() - mask where less than value""" .. _example-ma-operations-getdata-6: .. dropdown:: getdata (test_masked_arrays.py:234) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 224 :emphasize-lines: 11 np_mask = test_bind.np.array([False, True, False, True, False]) nc_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) nc_mask = test_bind.np.array([False, True, False, True, False]) np_masked = test_bind.np.ma.masked_array(np_data, mask=np_mask) nc_masked = test_bind.numpycore.ma.masked_array(nc_data, mask=nc_mask) # Extract data np_extracted = test_bind.np.ma.getdata(np_masked) nc_extracted = test_bind.numpycore.ma.getdata(nc_masked) assert_arrays_equal(np_extracted, nc_extracted, "getdata: extract data") print(f"\n[OK] ma.getdata() tests passed") return True def test_getmask(): """Test np.ma.getmask() - extract mask array""" print("\n" + "="*80) .. _example-ma-operations-getmask-7: .. dropdown:: getmask (test_masked_arrays.py:260) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 250 :emphasize-lines: 11 np_mask = test_bind.np.array([False, True, False, True, False]) nc_data = test_bind.np.array([1.0, 2.0, 3.0, 4.0, 5.0]) nc_mask = test_bind.np.array([False, True, False, True, False]) np_masked = test_bind.np.ma.masked_array(np_data, mask=np_mask) nc_masked = test_bind.numpycore.ma.masked_array(nc_data, mask=nc_mask) # Extract mask np_extracted_mask = test_bind.np.ma.getmask(np_masked) nc_extracted_mask = test_bind.numpycore.ma.getmask(nc_masked) assert_arrays_equal(np_extracted_mask, nc_extracted_mask, "getmask: extract mask") print(f"\n[OK] ma.getmask() tests passed") return True # ============================================================================ # Math Functions Tests # ============================================================================ .. _example-ma-operations-is_masked-8: .. dropdown:: is_masked (test_masked_week16_utilities.py:31) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 21 :emphasize-lines: 11 def test_is_masked(): """Test ma.is_masked module function""" print("\n[TEST] ma.is_masked()") # Test with masked data data = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float64) mask = np.array([False, True, False, False], dtype=bool) nc_ma = test_bind.numpycore.ma.masked_array(data, mask=mask) result = test_bind.numpycore.ma.is_masked(nc_ma) assert result == True, "Array with masked elements should return True" # Test with no masked data mask_none = np.array([False, False, False, False], dtype=bool) nc_ma_none = test_bind.numpycore.ma.masked_array(data, mask=mask_none) result_none = test_bind.numpycore.ma.is_masked(nc_ma_none) assert result_none == False, "Array with no masked elements should return False" f_print_success("ma.is_masked() passed")