MultiIndex ========== .. currentmodule:: pandasCore .. class:: MultiIndex A multi-level, or hierarchical, index object for pandas objects. Example ------- .. code-block:: python import pandasCore as pd # Create MultiIndex idx = pd.MultiIndex([1, 2, 3], name='my_index') print(len(idx)) # 3 Attributes ---------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Attribute - Description - Example * - :attr:`~MultiIndex.codes` - Return the codes (integer positions into levels) for each level - * - :attr:`~MultiIndex.dtypes` - Return the dtypes of the levels - * - :attr:`~MultiIndex.empty` - Indicator whether MultiIndex is empty - :ref:`View ` * - :attr:`~MultiIndex.has_duplicates` - Check if the MultiIndex has duplicate tuples - :ref:`View ` * - :attr:`~MultiIndex.is_monotonic_decreasing` - Return if the index is monotonic decreasing - * - :attr:`~MultiIndex.is_monotonic_increasing` - Return if the index is monotonic increasing - * - :attr:`~MultiIndex.is_unique` - Return if the index has unique values - :ref:`View ` * - :attr:`~MultiIndex.levels` - Return the levels (unique values) for each level of the MultiIndex - * - :attr:`~MultiIndex.levshape` - A tuple with the length of each level - :ref:`View ` * - :attr:`~MultiIndex.names` - Names of the levels in the MultiIndex - :ref:`View ` * - :attr:`~MultiIndex.ndim` - Number of dimensions (always 1) - :ref:`View ` * - :attr:`~MultiIndex.nlevels` - Number of levels in the MultiIndex - :ref:`View ` * - :attr:`~MultiIndex.shape` - Return a tuple of the shape of the underlying data - :ref:`View ` * - :attr:`~MultiIndex.size` - Return the number of elements in the MultiIndex - :ref:`View ` * - :attr:`~MultiIndex.str` - Vectorized string functions for Index. - :ref:`View ` Construction ------------ .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.__init__` ``(*args, **kwargs) | () | (levels: object = None, codes: object = None, sortorder: object = None, names: object = None, dtype: object = None, copy: bool = False, name: object = None, verify_integrity: bool = True)`` - Create an empty MultiIndex - :ref:`View ` Indexing / Selection -------------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.__getitem__` ``(index: typing.SupportsInt)`` - Get tuple at position - * - :meth:`~MultiIndex.take` ``(indices: list, axis: typing.SupportsInt = 0, allow_fill: bool = True, fill_value: object = None, **kwargs)`` - Return a new MultiIndex of the values selected by the indices. - :ref:`View ` * - :meth:`~MultiIndex.where` ``(cond: collections.abc.Sequence[bool], other: object = None)`` - Replace values where the condition is False. - Data Manipulation ----------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.drop` ``(codes: list, level: object = None, errors: str = 'raise')`` - Make new MultiIndex with passed labels removed. - :ref:`View ` * - :meth:`~MultiIndex.droplevel` ``(level: object = 0)`` - Return MultiIndex with requested level removed. - :ref:`View ` * - :meth:`~MultiIndex.insert` ``(loc: typing.SupportsInt, item: tuple)`` - Make new MultiIndex inserting new item at location. - :ref:`View ` * - :meth:`~MultiIndex.reindex` ``(target: pandasCore.MultiIndex, method: object = None, level: object = None, limit: object = None, tolerance: object = None)`` - Conform MultiIndex to new index. - * - :meth:`~MultiIndex.rename` ``(names: object, *, level: object = None, inplace: bool = False)`` - Alter MultiIndex name(s). - :ref:`View ` * - :meth:`~MultiIndex.reorder_levels` ``(order: list)`` - Rearrange levels using input order. - :ref:`View ` * - :meth:`~MultiIndex.set_names` ``(names: object, *, level: object = None, inplace: bool = False)`` - Set Index names. - :ref:`View ` * - :meth:`~MultiIndex.swaplevel` ``(i: typing.SupportsInt = -2, j: typing.SupportsInt = -1)`` - Swap level i with level j. - :ref:`View ` Missing Data ------------ .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.dropna` ``(how: str = 'any')`` - Return MultiIndex without NA/NaN values. - * - :meth:`~MultiIndex.fillna` ``(value: object = None, downcast: object = None)`` - Fill NA/NaN values with the specified value. - * - :meth:`~MultiIndex.isna` ``()`` - Detect missing values. - :ref:`View ` * - :meth:`~MultiIndex.isnull` ``()`` - Alias for isna() - * - :meth:`~MultiIndex.notna` ``()`` - Detect existing (non-missing) values. - :ref:`View ` * - :meth:`~MultiIndex.notnull` ``()`` - Alias for notna() - Statistics ---------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.max` ``(axis: object = None, skipna: bool = True, *args, **kwargs)`` - Return the maximum value of the MultiIndex (lexicographically). - :ref:`View ` * - :meth:`~MultiIndex.min` ``(axis: object = None, skipna: bool = True, *args, **kwargs)`` - Return the minimum value of the MultiIndex (lexicographically). - :ref:`View ` * - :meth:`~MultiIndex.nunique` ``(dropna: bool = True)`` - Return number of unique tuples in the MultiIndex. - :ref:`View ` * - :meth:`~MultiIndex.value_counts` ``(normalize: bool = False, sort: bool = True, ascending: bool = False, bins: object = None, dropna: bool = True)`` - Return a dict containing counts of unique tuples. - :ref:`View ` Aggregation ----------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.groupby` ``(values: collections.abc.Sequence[str])`` - Group the index labels by a given array of values. - * - :meth:`~MultiIndex.map` ``(mapper: collections.abc.Callable, na_action: object = None)`` - Map values using an input mapping or function. - Comparison ---------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.__eq__` ``(self, value, /)`` - Return self==value. - * - :meth:`~MultiIndex.__ge__` ``(self, value, /)`` - Return self>=value. - * - :meth:`~MultiIndex.__gt__` ``(self, value, /)`` - Return self>value. - * - :meth:`~MultiIndex.__le__` ``(self, value, /)`` - Return self<=value. - * - :meth:`~MultiIndex.__lt__` ``(self, value, /)`` - Return self` * - :meth:`~MultiIndex.searchsorted` ``(value: tuple, side: str = 'left', sorter: object = None)`` - Find indices where elements should be inserted to maintain order. - * - :meth:`~MultiIndex.sort_values` ``(*, return_indexer: bool = False, ascending: bool = True, na_position: str = 'last', key: object = None)`` - Return a sorted copy of the MultiIndex. - :ref:`View ` Reshaping --------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.to_frame` ``(index: bool = True, name: object = None, allow_duplicates: bool = False)`` - Create a DataFrame with the levels of the MultiIndex as columns. - :ref:`View ` * - :meth:`~MultiIndex.transpose` ``(*args, **kwargs) | (*args, **kwargs) | (*args, **kwargs)`` - Return the transpose. - Combining --------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.append` ``(other: pandasCore.MultiIndex)`` - Append a MultiIndex to the current one. - * - :meth:`~MultiIndex.join` ``(other: pandasCore.MultiIndex, *, how: str = 'left', level: object = None, return_indexers: bool = False, sort: bool = False)`` - Compute join of two MultiIndex objects. - Time Series ----------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.asof` ``(label: tuple)`` - Return the label from the index, or, if not present, the previous one. - * - :meth:`~MultiIndex.diff` ``(periods: typing.SupportsInt = 1)`` - Compute the difference between consecutive elements. - * - :meth:`~MultiIndex.shift` ``(periods: typing.SupportsInt = 1, freq: object = None)`` - Shift index by desired number of periods. - I/O --- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.to_flat_index` ``()`` - Convert a MultiIndex to an Index of Tuples. - :ref:`View ` * - :meth:`~MultiIndex.to_list` ``()`` - Alias for tolist() - * - :meth:`~MultiIndex.to_numpy` ``(dtype: object = None, copy: bool = False, na_value: object = None, **kwargs)`` - Return a numpy ndarray of the values. - :ref:`View ` * - :meth:`~MultiIndex.to_series` ``(index: object = None, name: object = None)`` - Create a Series with both index and values from the index. - * - :meth:`~MultiIndex.tolist` ``()`` - Return a list of tuples. - :ref:`View ` Conversion ---------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.astype` ``(dtype: str, copy: bool = True)`` - Cast to a specified dtype. - * - :meth:`~MultiIndex.copy` ``(names: object = None, deep: bool = False, name: object = None)`` - Make a copy of this object. - :ref:`View ` * - :meth:`~MultiIndex.infer_objects` ``(copy: bool = True)`` - Attempt to infer better dtypes for object columns. - :ref:`View ` * - :meth:`~MultiIndex.view` ``(cls: object = None)`` - Return a view of the index. - :ref:`View ` Iteration --------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.__contains__` ``(key: tuple)`` - Check if key is contained in MultiIndex - * - :meth:`~MultiIndex.__iter__` ``()`` - - * - :meth:`~MultiIndex.__len__` ``()`` - Return the number of elements - Set Operations -------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.difference` ``(other: pandasCore.MultiIndex, sort: object = None)`` - Return a new MultiIndex with elements from this not in other. - * - :meth:`~MultiIndex.drop_duplicates` ``(*, keep: str = 'first')`` - Return MultiIndex with duplicates removed. - :ref:`View ` * - :meth:`~MultiIndex.duplicated` ``(keep: str = 'first')`` - Indicate duplicate values. - :ref:`View ` * - :meth:`~MultiIndex.intersection` ``(other: pandasCore.MultiIndex, sort: bool = False)`` - Form the intersection of two MultiIndex objects. - * - :meth:`~MultiIndex.isin` ``(values: list, level: object = None)`` - Check if values are contained in MultiIndex. - :ref:`View ` * - :meth:`~MultiIndex.symmetric_difference` ``(other: pandasCore.MultiIndex, result_name: object = None, sort: object = None)`` - Return the symmetric difference of two MultiIndex objects. - * - :meth:`~MultiIndex.union` ``(other: pandasCore.MultiIndex, sort: object = None)`` - Form the union of two MultiIndex objects. - * - :meth:`~MultiIndex.unique` ``(level: object = None)`` - Return unique values in the MultiIndex. - :ref:`View ` String Methods -------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.contains` ``(key: tuple)`` - Check if key is contained in MultiIndex. - :ref:`View ` Datetime Methods ---------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.round` ``(decimals: typing.SupportsInt = 0)`` - Round the index values to the given number of decimals. - Other Methods ------------- .. list-table:: :widths: 25 60 15 :header-rows: 1 * - Method - Description - Example * - :meth:`~MultiIndex.__hash__` ``(self, /)`` - Return hash(self). - * - :meth:`~MultiIndex.__repr__` ``()`` - - * - :meth:`~MultiIndex.__str__` ``()`` - - * - :meth:`~MultiIndex.all` ``(*args, **kwargs)`` - Return whether all elements are True. - * - :meth:`~MultiIndex.any` ``(*args, **kwargs)`` - Return whether any element is True. - * - :meth:`~MultiIndex.argmax` ``(axis: object = None, skipna: bool = True, *args, **kwargs)`` - Return position of maximum value. - :ref:`View ` * - :meth:`~MultiIndex.argmin` ``(axis: object = None, skipna: bool = True, *args, **kwargs)`` - Return position of minimum value. - :ref:`View ` * - :meth:`~MultiIndex.asof_locs` ``(where: list, mask: collections.abc.Sequence[bool] | None = None)`` - Return the locations (indices) of labels in the index. - * - :meth:`~MultiIndex.delete` ``(loc: typing.SupportsInt)`` - Make new MultiIndex with passed location deleted. - :ref:`View ` * - :meth:`~MultiIndex.equal_levels` ``(other: pandasCore.MultiIndex)`` - Return True if the levels of both MultiIndex are the same. - * - :meth:`~MultiIndex.factorize` ``(sort: bool = False, use_na_sentinel: bool = True)`` - Encode the object as an enumerated type. - :ref:`View ` * - :meth:`~MultiIndex.format` ``(name: object = None, formatter: object = None, na_rep: object = None, names: bool = False, space: typing.SupportsInt = 2, sparsify: object = None, adjoin: bool = True)`` - Render a string representation of the MultiIndex. - :ref:`View ` * - :meth:`~MultiIndex.get_indexer` ``(target: pandasCore.MultiIndex, method: object = None, limit: object = None, tolerance: object = None)`` - Compute indexer and mask for new index given the current index. - * - :meth:`~MultiIndex.get_indexer_for` ``(target: pandasCore.MultiIndex)`` - Get indexer for target values (alias for get_indexer). - * - :meth:`~MultiIndex.get_indexer_non_unique` ``(target: pandasCore.MultiIndex)`` - Compute indexer and mask for new index allowing non-unique values. - * - :meth:`~MultiIndex.get_level_values` ``(level: object)`` - Return vector of label values for requested level. - :ref:`View ` * - :meth:`~MultiIndex.get_loc` ``(key: tuple)`` - Get integer location for requested label. - :ref:`View ` * - :meth:`~MultiIndex.get_loc_level` ``(key: str, level: typing.SupportsInt = 0, drop_level: bool = True)`` - Get location and sliced index for requested label/level. - * - :meth:`~MultiIndex.get_locs` ``(seq: list)`` - Get locations for a sequence of labels. - * - :meth:`~MultiIndex.get_slice_bound` ``(label: tuple, side: str)`` - Calculate slice bound that corresponds to given label. - * - :meth:`~MultiIndex.holds_integer` ``()`` - Return True if all levels contain integer type - * - :meth:`~MultiIndex.identical` ``(other: pandasCore.MultiIndex)`` - Similar to equals, but check that metadata are also the same. - * - :meth:`~MultiIndex.item` ``()`` - Return the first element as a scalar. - * - :meth:`~MultiIndex.memory_usage` ``(deep: bool = False)`` - Memory usage of the values. - :ref:`View ` * - :meth:`~MultiIndex.putmask` ``(mask: collections.abc.Sequence[bool], value: tuple)`` - Return a new MultiIndex with values put where mask is True. - * - :meth:`~MultiIndex.ravel` ``(order: str = 'C')`` - Return a flattened representation. - :ref:`View ` * - :meth:`~MultiIndex.remove_unused_levels` ``()`` - Create new MultiIndex from current with unused levels removed. - * - :meth:`~MultiIndex.repeat` ``(repeats: typing.SupportsInt, axis: object = None)`` - Repeat elements of a MultiIndex. - :ref:`View ` * - :meth:`~MultiIndex.set_codes` ``(codes: list, *, level: object = None, verify_integrity: bool = True)`` - Set new codes on MultiIndex. - * - :meth:`~MultiIndex.set_levels` ``(levels: list, *, level: object = None, verify_integrity: bool = True)`` - Set new levels on MultiIndex. - * - :meth:`~MultiIndex.slice_indexer` ``(start: object = None, end: object = None, step: object = None)`` - Compute slice locations for input labels. - :ref:`View ` * - :meth:`~MultiIndex.slice_locs` ``(start: object = None, end: object = None, step: object = None)`` - Compute slice locations for input labels. - * - :meth:`~MultiIndex.sort` ``(ascending: bool = True)`` - Return a sorted copy of the index. - * - :meth:`~MultiIndex.sortlevel` ``(level: object = 0, ascending: bool = True, sort_remaining: bool = True, na_position: str = 'first')`` - Sort MultiIndex at the specified level. - :ref:`View ` * - :meth:`~MultiIndex.truncate` ``(before: object = None, after: object = None)`` - Truncate a sorted MultiIndex. - Code Examples ------------- The following examples are extracted from the test suite. .. _example-multiindex-empty-0: .. dropdown:: empty (test_multiindex.py:113) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 103 :emphasize-lines: 11 f_print_info("Testing MultiIndex properties...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Test basic properties ctx.assert_equal(4, mi.size, "property: size") ctx.assert_equal(2, mi.nlevels, "property: nlevels") ctx.assert_equal(1, mi.ndim, "property: ndim") ctx.assert_equal((4,), mi.shape, "property: shape") ctx.assert_false(mi.empty, "property: empty") # Test unique/duplicates properties ctx.assert_true(mi.is_unique, "property: is_unique") ctx.assert_false(mi.has_duplicates, "property: has_duplicates") # Test with duplicates dup_arrays = [['a', 'a', 'a', 'b'], ['one', 'one', 'two', 'one']] mi_dup = pandasCore.MultiIndex.from_arrays(dup_arrays) ctx.assert_false(mi_dup.is_unique, "property with duplicates: is_unique") ctx.assert_true(mi_dup.has_duplicates, "property with duplicates: has_duplicates") .. _example-multiindex-has_duplicates-1: .. dropdown:: has_duplicates (test_multiindex.py:117) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 107 :emphasize-lines: 11 # Test basic properties ctx.assert_equal(4, mi.size, "property: size") ctx.assert_equal(2, mi.nlevels, "property: nlevels") ctx.assert_equal(1, mi.ndim, "property: ndim") ctx.assert_equal((4,), mi.shape, "property: shape") ctx.assert_false(mi.empty, "property: empty") # Test unique/duplicates properties ctx.assert_true(mi.is_unique, "property: is_unique") ctx.assert_false(mi.has_duplicates, "property: has_duplicates") # Test with duplicates dup_arrays = [['a', 'a', 'a', 'b'], ['one', 'one', 'two', 'one']] mi_dup = pandasCore.MultiIndex.from_arrays(dup_arrays) ctx.assert_false(mi_dup.is_unique, "property with duplicates: is_unique") ctx.assert_true(mi_dup.has_duplicates, "property with duplicates: has_duplicates") def test_levshape(): """Test levshape property""" .. _example-multiindex-is_unique-2: .. dropdown:: is_unique (test_multiindex.py:116) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 106 :emphasize-lines: 11 mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Test basic properties ctx.assert_equal(4, mi.size, "property: size") ctx.assert_equal(2, mi.nlevels, "property: nlevels") ctx.assert_equal(1, mi.ndim, "property: ndim") ctx.assert_equal((4,), mi.shape, "property: shape") ctx.assert_false(mi.empty, "property: empty") # Test unique/duplicates properties ctx.assert_true(mi.is_unique, "property: is_unique") ctx.assert_false(mi.has_duplicates, "property: has_duplicates") # Test with duplicates dup_arrays = [['a', 'a', 'a', 'b'], ['one', 'one', 'two', 'one']] mi_dup = pandasCore.MultiIndex.from_arrays(dup_arrays) ctx.assert_false(mi_dup.is_unique, "property with duplicates: is_unique") ctx.assert_true(mi_dup.has_duplicates, "property with duplicates: has_duplicates") def test_levshape(): .. _example-multiindex-levshape-3: .. dropdown:: levshape (test_multiindex.py:133) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 123 :emphasize-lines: 11 ctx.assert_true(mi_dup.has_duplicates, "property with duplicates: has_duplicates") def test_levshape(): """Test levshape property""" f_print_info("Testing levshape property...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) levshape = mi.levshape # First level has 2 unique values ('a', 'b'), second has 2 ('one', 'two') ctx.assert_equal(2, levshape[0], "levshape: level 0") ctx.assert_equal(2, levshape[1], "levshape: level 1") def test_monotonic(): """Test is_monotonic_increasing and is_monotonic_decreasing""" f_print_info("Testing monotonic properties...") # Create sorted MultiIndex .. _example-multiindex-names-4: .. dropdown:: names (test_multiindex.py:45) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 35 :emphasize-lines: 11 """Test MultiIndex.from_arrays""" f_print_info("Testing MultiIndex.from_arrays...") # Create from arrays arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Check basic properties ctx.assert_equal(4, mi.size, "from_arrays: size") ctx.assert_equal(2, mi.nlevels, "from_arrays: nlevels") ctx.assert_list_equal(['first', 'second'], mi.names, "from_arrays: names") # Test without names mi2 = pandasCore.MultiIndex.from_arrays(arrays) ctx.assert_equal(4, mi2.size, "from_arrays without names: size") def test_from_tuples(): """Test MultiIndex.from_tuples""" f_print_info("Testing MultiIndex.from_tuples...") .. _example-multiindex-ndim-5: .. dropdown:: ndim (test_multiindex.py:111) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 101 :emphasize-lines: 11 def test_properties(): """Test MultiIndex properties""" f_print_info("Testing MultiIndex properties...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Test basic properties ctx.assert_equal(4, mi.size, "property: size") ctx.assert_equal(2, mi.nlevels, "property: nlevels") ctx.assert_equal(1, mi.ndim, "property: ndim") ctx.assert_equal((4,), mi.shape, "property: shape") ctx.assert_false(mi.empty, "property: empty") # Test unique/duplicates properties ctx.assert_true(mi.is_unique, "property: is_unique") ctx.assert_false(mi.has_duplicates, "property: has_duplicates") # Test with duplicates dup_arrays = [['a', 'a', 'a', 'b'], ['one', 'one', 'two', 'one']] mi_dup = pandasCore.MultiIndex.from_arrays(dup_arrays) .. _example-multiindex-nlevels-6: .. dropdown:: nlevels (test_multiindex.py:44) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 34 :emphasize-lines: 11 def test_from_arrays(): """Test MultiIndex.from_arrays""" f_print_info("Testing MultiIndex.from_arrays...") # Create from arrays arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Check basic properties ctx.assert_equal(4, mi.size, "from_arrays: size") ctx.assert_equal(2, mi.nlevels, "from_arrays: nlevels") ctx.assert_list_equal(['first', 'second'], mi.names, "from_arrays: names") # Test without names mi2 = pandasCore.MultiIndex.from_arrays(arrays) ctx.assert_equal(4, mi2.size, "from_arrays without names: size") def test_from_tuples(): """Test MultiIndex.from_tuples""" f_print_info("Testing MultiIndex.from_tuples...") .. _example-multiindex-shape-7: .. dropdown:: shape (test_multiindex.py:112) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 102 :emphasize-lines: 11 """Test MultiIndex properties""" f_print_info("Testing MultiIndex properties...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Test basic properties ctx.assert_equal(4, mi.size, "property: size") ctx.assert_equal(2, mi.nlevels, "property: nlevels") ctx.assert_equal(1, mi.ndim, "property: ndim") ctx.assert_equal((4,), mi.shape, "property: shape") ctx.assert_false(mi.empty, "property: empty") # Test unique/duplicates properties ctx.assert_true(mi.is_unique, "property: is_unique") ctx.assert_false(mi.has_duplicates, "property: has_duplicates") # Test with duplicates dup_arrays = [['a', 'a', 'a', 'b'], ['one', 'one', 'two', 'one']] mi_dup = pandasCore.MultiIndex.from_arrays(dup_arrays) ctx.assert_false(mi_dup.is_unique, "property with duplicates: is_unique") .. _example-multiindex-size-8: .. dropdown:: size (test_interval_multi_range_str.py:122) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 112 :emphasize-lines: 11 assert 'IndexStringAccessorType' in str(accessor_type), \ f"Expected IndexStringAccessorType, got {accessor_type}" print(" PASSED: type(MultiIndex.str) is IndexStringAccessorType") def test_multiindex_str_instance_access(): """Test MultiIndex instance .str access.""" print("Testing MultiIndex instance .str access...") # Create a MultiIndex mi = pandasCore.MultiIndex.from_arrays([[1, 2, 3], [4, 5, 6]], names=['first', 'second']) print(f" Created MultiIndex with {mi.size} elements") # Access .str - this should either work or raise an appropriate error # since MultiIndex values are tuples, not strings try: str_methods = mi.str print(f" mi.str type: {type(str_methods)}") print(" PASSED: MultiIndex.str accessor is accessible") except Exception as e: # Expected to raise error since MultiIndex doesn't contain strings print(f" Error (expected for non-string data): {e}") .. _example-multiindex-str-9: .. dropdown:: str (test_interval_multi_range_str.py:127) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 117 :emphasize-lines: 11 """Test MultiIndex instance .str access.""" print("Testing MultiIndex instance .str access...") # Create a MultiIndex mi = pandasCore.MultiIndex.from_arrays([[1, 2, 3], [4, 5, 6]], names=['first', 'second']) print(f" Created MultiIndex with {mi.size} elements") # Access .str - this should either work or raise an appropriate error # since MultiIndex values are tuples, not strings try: str_methods = mi.str print(f" mi.str type: {type(str_methods)}") print(" PASSED: MultiIndex.str accessor is accessible") except Exception as e: # Expected to raise error since MultiIndex doesn't contain strings print(f" Error (expected for non-string data): {e}") print(" PASSED: Appropriate error raised for non-string Index") def test_multiindex_str_call_with_data(): """Test MultiIndex.str(data) call.""" print("Testing MultiIndex.str(data) call...") .. _example-multiindex-dunder-initdunder--10: .. dropdown:: __init__ (test_multiindex.py:693) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 683 :emphasize-lines: 11 # ============================================================================= # Empty MultiIndex Tests # ============================================================================= def test_empty_multiindex(): """Test empty MultiIndex""" f_print_info("Testing empty MultiIndex...") mi = pandasCore.MultiIndex() ctx.assert_equal(0, mi.size, "empty: size") ctx.assert_true(mi.empty, "empty: empty property") # ============================================================================= # Main Function # ============================================================================= def f_main(): .. _example-multiindex-take-11: .. dropdown:: take (test_multiindex.py:458) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 448 :emphasize-lines: 11 # Manipulation Methods Tests # ============================================================================= def test_take(): """Test take method""" f_print_info("Testing take method...") arrays = [['a', 'b', 'c', 'd'], ['one', 'two', 'three', 'four']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_taken = mi.take([0, 2]) ctx.assert_equal(2, mi_taken.size, "take: size") ctx.assert_equal(('a', 'one'), mi_taken[0], "take: first element") ctx.assert_equal(('c', 'three'), mi_taken[1], "take: second element") def test_insert(): """Test insert method""" f_print_info("Testing insert method...") arrays = [['a', 'c'], ['one', 'three']] .. _example-multiindex-drop-12: .. dropdown:: drop (test_signature_phase14.py:34) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 24 :emphasize-lines: 11 # Should accept name parameter result = mi.copy(names=None, deep=False, name=None) assert result is not None, "copy should return result" print(" copy: OK") def test_drop(): """Test drop has level and errors parameters""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2'), ('c', '3')], names=['x', 'y']) # Should accept level and errors result = mi.drop([('a', '1')], level=None, errors='raise') assert result is not None, "drop should return result" print(" drop: OK") def test_drop_duplicates(): """Test drop_duplicates has keyword-only keep""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept keep as keyword-only result = mi.drop_duplicates(keep='first') assert result is not None, "drop_duplicates should return result" .. _example-multiindex-droplevel-13: .. dropdown:: droplevel (test_multiindex.py:219) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 209 :emphasize-lines: 11 def test_droplevel(): """Test droplevel method""" f_print_info("Testing droplevel method...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Drop first level mi_dropped = mi.droplevel(0) ctx.assert_equal(1, mi_dropped.nlevels, "droplevel: nlevels reduced") ctx.assert_list_equal(['second'], mi_dropped.names, "droplevel: correct name remaining") def test_swaplevel(): """Test swaplevel method""" f_print_info("Testing swaplevel method...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) .. _example-multiindex-insert-14: .. dropdown:: insert (test_multiindex.py:471) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 461 :emphasize-lines: 11 ctx.assert_equal(('c', 'three'), mi_taken[1], "take: second element") def test_insert(): """Test insert method""" f_print_info("Testing insert method...") arrays = [['a', 'c'], ['one', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_inserted = mi.insert(1, ('b', 'two')) ctx.assert_equal(3, mi_inserted.size, "insert: size") ctx.assert_equal(('b', 'two'), mi_inserted[1], "insert: inserted element") def test_delete(): """Test delete method""" f_print_info("Testing delete method...") arrays = [['a', 'b', 'c'], ['one', 'two', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) .. _example-multiindex-rename-15: .. dropdown:: rename (test_signature_phase14.py:159) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 149 :emphasize-lines: 11 # Should accept order result = mi.ravel(order='C') assert result is not None, "ravel should return result" print(" ravel: OK") def test_rename(): """Test rename has level parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept level result = mi.rename(['new_x', 'new_y'], level=None, inplace=False) assert result is not None, "rename should return result" print(" rename: OK") def test_repeat(): """Test repeat has axis parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept axis result = mi.repeat(2, axis=None) assert result is not None, "repeat should return result" .. _example-multiindex-reorder_levels-16: .. dropdown:: reorder_levels (test_multiindex.py:247) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 237 :emphasize-lines: 11 ctx.assert_equal('a', first_tuple[1], "swaplevel: first element level 1") def test_reorder_levels(): """Test reorder_levels method""" f_print_info("Testing reorder_levels method...") arrays = [['a', 'a'], ['one', 'two'], ['x', 'y']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second', 'third']) mi_reordered = mi.reorder_levels([2, 0, 1]) ctx.assert_list_equal(['third', 'first', 'second'], mi_reordered.names, "reorder_levels: names reordered") # ============================================================================= # MultiIndex-specific Methods Tests # ============================================================================= def test_to_flat_index(): """Test to_flat_index method""" f_print_info("Testing to_flat_index method...") .. _example-multiindex-set_names-17: .. dropdown:: set_names (test_multiindex.py:180) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 170 :emphasize-lines: 11 def test_rename_set_names(): """Test rename and set_names methods""" f_print_info("Testing rename and set_names methods...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) # Test set_names mi_named = mi.set_names(['first', 'second']) ctx.assert_list_equal(['first', 'second'], mi_named.names, "set_names: names set") # Test rename mi_renamed = mi_named.rename(['A', 'B']) ctx.assert_list_equal(['A', 'B'], mi_renamed.names, "rename: names changed") # ============================================================================= # Level Management Tests # ============================================================================= .. _example-multiindex-swaplevel-18: .. dropdown:: swaplevel (test_multiindex.py:231) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 221 :emphasize-lines: 11 ctx.assert_list_equal(['second'], mi_dropped.names, "droplevel: correct name remaining") def test_swaplevel(): """Test swaplevel method""" f_print_info("Testing swaplevel method...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) mi_swapped = mi.swaplevel(0, 1) ctx.assert_list_equal(['second', 'first'], mi_swapped.names, "swaplevel: names swapped") # Check that values are swapped first_tuple = mi_swapped[0] ctx.assert_equal('one', first_tuple[0], "swaplevel: first element level 0") ctx.assert_equal('a', first_tuple[1], "swaplevel: first element level 1") def test_reorder_levels(): """Test reorder_levels method""" .. _example-multiindex-isna-19: .. dropdown:: isna (test_multiindex.py:526) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 516 :emphasize-lines: 11 # ============================================================================= def test_na_methods(): """Test NA-related methods""" f_print_info("Testing NA-related methods...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) # isna should return all False isna = mi.isna() ctx.assert_list_equal([False, False], isna, "isna: all False") # notna should return all True notna = mi.notna() ctx.assert_list_equal([True, True], notna, "notna: all True") # ============================================================================= # Duplicate Handling Tests # ============================================================================= .. _example-multiindex-notna-20: .. dropdown:: notna (test_multiindex.py:530) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 520 :emphasize-lines: 11 f_print_info("Testing NA-related methods...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) # isna should return all False isna = mi.isna() ctx.assert_list_equal([False, False], isna, "isna: all False") # notna should return all True notna = mi.notna() ctx.assert_list_equal([True, True], notna, "notna: all True") # ============================================================================= # Duplicate Handling Tests # ============================================================================= def test_drop_duplicates(): """Test drop_duplicates method""" f_print_info("Testing drop_duplicates method...") .. _example-multiindex-max-21: .. dropdown:: max (test_multiindex.py:305) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 295 :emphasize-lines: 11 # ============================================================================= def test_min_max(): """Test min and max methods""" f_print_info("Testing min and max methods...") arrays = [['a', 'b', 'c'], ['one', 'two', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) min_val = mi.min() max_val = mi.max() f_print_info(f" min: {min_val}") f_print_info(f" max: {max_val}") # Just verify we get tuples back ctx.assert_equal(2, len(min_val), "min: returns tuple of length 2") ctx.assert_equal(2, len(max_val), "max: returns tuple of length 2") def test_argmin_argmax(): .. _example-multiindex-min-22: .. dropdown:: min (test_multiindex.py:304) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 294 :emphasize-lines: 11 # Statistics Methods Tests # ============================================================================= def test_min_max(): """Test min and max methods""" f_print_info("Testing min and max methods...") arrays = [['a', 'b', 'c'], ['one', 'two', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) min_val = mi.min() max_val = mi.max() f_print_info(f" min: {min_val}") f_print_info(f" max: {max_val}") # Just verify we get tuples back ctx.assert_equal(2, len(min_val), "min: returns tuple of length 2") ctx.assert_equal(2, len(max_val), "max: returns tuple of length 2") .. _example-multiindex-nunique-23: .. dropdown:: nunique (test_multiindex.py:340) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 330 :emphasize-lines: 11 ctx.assert_true(isinstance(argmax, int), "argmax: returns int") def test_nunique(): """Test nunique method""" f_print_info("Testing nunique method...") # All unique arrays = [['a', 'b', 'c'], ['one', 'two', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) ctx.assert_equal(3, mi.nunique(), "nunique: all unique") # With duplicates dup_arrays = [['a', 'a', 'b'], ['one', 'one', 'two']] mi_dup = pandasCore.MultiIndex.from_arrays(dup_arrays) ctx.assert_equal(2, mi_dup.nunique(), "nunique: with duplicates") # ============================================================================= # Set Operations Tests # ============================================================================= .. _example-multiindex-value_counts-24: .. dropdown:: value_counts (test_signature_phase14.py:223) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 213 :emphasize-lines: 11 # Should accept level result = mi.unique(level=None) assert result is not None, "unique should return result" print(" unique: OK") def test_value_counts(): """Test value_counts has normalize and bins parameters""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept normalize and bins result = mi.value_counts(normalize=False, sort=True, ascending=False, bins=None, dropna=True) assert result is not None, "value_counts should return result" print(" value_counts: OK") def test_view(): """Test view has cls parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept cls result = mi.view(cls=None) assert result is not None, "view should return result" .. _example-multiindex-argsort-25: .. dropdown:: argsort (test_multiindex.py:510) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 500 :emphasize-lines: 11 f_print_info(f" First after sort: {first}") def test_argsort(): """Test argsort method""" f_print_info("Testing argsort method...") arrays = [['c', 'a', 'b'], ['three', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) indices = mi.argsort() ctx.assert_equal(3, len(indices), "argsort: length") # ============================================================================= # NA Handling Tests (MultiIndex has no NAs, but API should work) # ============================================================================= def test_na_methods(): """Test NA-related methods""" f_print_info("Testing NA-related methods...") .. _example-multiindex-sort_values-26: .. dropdown:: sort_values (test_multiindex.py:496) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 486 :emphasize-lines: 11 ctx.assert_equal(('c', 'three'), mi_deleted[1], "delete: second element") def test_sort_values(): """Test sort_values method""" f_print_info("Testing sort_values method...") arrays = [['c', 'a', 'b'], ['three', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_sorted = mi.sort_values() # First element should be lexicographically smallest first = mi_sorted[0] f_print_info(f" First after sort: {first}") def test_argsort(): """Test argsort method""" f_print_info("Testing argsort method...") .. _example-multiindex-to_frame-27: .. dropdown:: to_frame (test_multiindex.py:275) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 265 :emphasize-lines: 11 ctx.assert_equal(('b', 'two'), flat[1], "to_flat_index: second tuple") def test_to_frame(): """Test to_frame method""" f_print_info("Testing to_frame method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) frame = mi.to_frame() ctx.assert_true('first' in frame or 'level_0' in frame, "to_frame: has column") def test_sortlevel(): """Test sortlevel method""" f_print_info("Testing sortlevel method...") arrays = [['b', 'a', 'b', 'a'], ['two', 'one', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) .. _example-multiindex-to_flat_index-28: .. dropdown:: to_flat_index (test_multiindex.py:262) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 252 :emphasize-lines: 11 # MultiIndex-specific Methods Tests # ============================================================================= def test_to_flat_index(): """Test to_flat_index method""" f_print_info("Testing to_flat_index method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) flat = mi.to_flat_index() ctx.assert_equal(2, len(flat), "to_flat_index: length") ctx.assert_equal(('a', 'one'), flat[0], "to_flat_index: first tuple") ctx.assert_equal(('b', 'two'), flat[1], "to_flat_index: second tuple") def test_to_frame(): """Test to_frame method""" f_print_info("Testing to_frame method...") arrays = [['a', 'b'], ['one', 'two']] .. _example-multiindex-to_numpy-29: .. dropdown:: to_numpy (test_signature_phase14.py:205) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 195 :emphasize-lines: 11 # Should accept axis, allow_fill, fill_value result = mi.take([0, 1], axis=0, allow_fill=True, fill_value=None) assert result is not None, "take should return result" print(" take: OK") def test_to_numpy(): """Test to_numpy has dtype, copy, na_value parameters""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept dtype, copy, na_value result = mi.to_numpy(dtype=None, copy=False, na_value=None) assert result is not None, "to_numpy should return result" print(" to_numpy: OK") def test_unique(): """Test unique has level parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept level result = mi.unique(level=None) assert result is not None, "unique should return result" .. _example-multiindex-tolist-30: .. dropdown:: tolist (test_multiindex.py:623) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 613 :emphasize-lines: 11 ctx.assert_equal(mi[0], mi_repeated[1], "repeat: repeated first element") def test_tolist(): """Test tolist method""" f_print_info("Testing tolist method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) result = mi.tolist() ctx.assert_equal(2, len(result), "tolist: length") ctx.assert_equal(('a', 'one'), result[0], "tolist: first tuple") def test_memory_usage(): """Test memory_usage method""" f_print_info("Testing memory_usage method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) .. _example-multiindex-copy-31: .. dropdown:: copy (test_multiindex.py:165) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 155 :emphasize-lines: 11 # ============================================================================= # Core Methods Tests # ============================================================================= def test_copy(): """Test copy method""" f_print_info("Testing copy method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) mi_copy = mi.copy() ctx.assert_equal(mi.size, mi_copy.size, "copy: size preserved") ctx.assert_equal(mi.nlevels, mi_copy.nlevels, "copy: nlevels preserved") ctx.assert_list_equal(mi.names, mi_copy.names, "copy: names preserved") def test_rename_set_names(): """Test rename and set_names methods""" f_print_info("Testing rename and set_names methods...") .. _example-multiindex-infer_objects-32: .. dropdown:: infer_objects (test_signature_phase14.py:95) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 85 :emphasize-lines: 11 # Should accept sortorder mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], sortorder=None, names=None) assert mi is not None, "from_tuples should return MultiIndex" print(" from_tuples: OK") def test_infer_objects(): """Test infer_objects has copy parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept copy result = mi.infer_objects(copy=True) assert result is not None, "infer_objects should return result" print(" infer_objects: OK") def test_isin(): """Test isin has level parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept level result = mi.isin([('a', '1')], level=None) assert result is not None, "isin should return result" .. _example-multiindex-view-33: .. dropdown:: view (test_signature_phase14.py:232) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 222 :emphasize-lines: 11 # Should accept normalize and bins result = mi.value_counts(normalize=False, sort=True, ascending=False, bins=None, dropna=True) assert result is not None, "value_counts should return result" print(" value_counts: OK") def test_view(): """Test view has cls parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept cls result = mi.view(cls=None) assert result is not None, "view should return result" print(" view: OK") def f_main(): """Run all Phase 14 signature tests""" print("Phase 14: MultiIndex Missing Parameters Tests") print("=" * 50) tests = [ .. _example-multiindex-drop_duplicates-34: .. dropdown:: drop_duplicates (test_multiindex.py:545) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 535 :emphasize-lines: 11 # Duplicate Handling Tests # ============================================================================= def test_drop_duplicates(): """Test drop_duplicates method""" f_print_info("Testing drop_duplicates method...") arrays = [['a', 'a', 'b', 'a'], ['one', 'one', 'two', 'one']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_unique = mi.drop_duplicates() ctx.assert_equal(2, mi_unique.size, "drop_duplicates: size") def test_duplicated(): """Test duplicated method""" f_print_info("Testing duplicated method...") arrays = [['a', 'a', 'b', 'a'], ['one', 'one', 'two', 'one']] mi = pandasCore.MultiIndex.from_arrays(arrays) .. _example-multiindex-duplicated-35: .. dropdown:: duplicated (test_multiindex.py:556) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 546 :emphasize-lines: 11 ctx.assert_equal(2, mi_unique.size, "drop_duplicates: size") def test_duplicated(): """Test duplicated method""" f_print_info("Testing duplicated method...") arrays = [['a', 'a', 'b', 'a'], ['one', 'one', 'two', 'one']] mi = pandasCore.MultiIndex.from_arrays(arrays) dups = mi.duplicated() # First (a,one) is not dup, second is, (b,two) is not, third (a,one) is ctx.assert_false(dups[0], "duplicated: first occurrence not duplicate") ctx.assert_true(dups[1], "duplicated: second occurrence is duplicate") def test_unique(): """Test unique method""" f_print_info("Testing unique method...") arrays = [['a', 'a', 'b', 'a'], ['one', 'one', 'two', 'one']] .. _example-multiindex-isin-36: .. dropdown:: isin (test_multiindex.py:584) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 574 :emphasize-lines: 11 # Other Methods Tests # ============================================================================= def test_isin(): """Test isin method""" f_print_info("Testing isin method...") arrays = [['a', 'b', 'c'], ['one', 'two', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) result = mi.isin([('a', 'one'), ('c', 'three')]) ctx.assert_true(result[0], "isin: (a, one)") ctx.assert_false(result[1], "isin: (b, two) not in set") ctx.assert_true(result[2], "isin: (c, three)") def test_equals(): """Test equals method""" f_print_info("Testing equals method...") arrays = [['a', 'b'], ['one', 'two']] .. _example-multiindex-unique-37: .. dropdown:: unique (test_multiindex.py:569) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 559 :emphasize-lines: 11 ctx.assert_true(dups[1], "duplicated: second occurrence is duplicate") def test_unique(): """Test unique method""" f_print_info("Testing unique method...") arrays = [['a', 'a', 'b', 'a'], ['one', 'one', 'two', 'one']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_unique = mi.unique() ctx.assert_equal(2, mi_unique.size, "unique: size") # ============================================================================= # Other Methods Tests # ============================================================================= def test_isin(): """Test isin method""" f_print_info("Testing isin method...") .. _example-multiindex-contains-38: .. dropdown:: contains (test_multiindex.py:442) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 432 :emphasize-lines: 11 ctx.assert_equal(3, loc2, "get_loc: (b, two)") def test_contains(): """Test contains method""" f_print_info("Testing contains method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) ctx.assert_true(mi.contains(('a', 'one')), "contains: (a, one)") ctx.assert_true(mi.contains(('b', 'two')), "contains: (b, two)") ctx.assert_false(mi.contains(('a', 'two')), "contains: (a, two) not present") # ============================================================================= # Manipulation Methods Tests # ============================================================================= def test_take(): """Test take method""" .. _example-multiindex-argmax-39: .. dropdown:: argmax (test_multiindex.py:323) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 313 :emphasize-lines: 11 def test_argmin_argmax(): """Test argmin and argmax methods""" f_print_info("Testing argmin and argmax methods...") arrays = [['c', 'a', 'b'], ['three', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) argmin = mi.argmin() argmax = mi.argmax() f_print_info(f" argmin: {argmin}") f_print_info(f" argmax: {argmax}") # Verify we get integer indices ctx.assert_true(isinstance(argmin, int), "argmin: returns int") ctx.assert_true(isinstance(argmax, int), "argmax: returns int") def test_nunique(): .. _example-multiindex-argmin-40: .. dropdown:: argmin (test_multiindex.py:322) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 312 :emphasize-lines: 11 ctx.assert_equal(2, len(max_val), "max: returns tuple of length 2") def test_argmin_argmax(): """Test argmin and argmax methods""" f_print_info("Testing argmin and argmax methods...") arrays = [['c', 'a', 'b'], ['three', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) argmin = mi.argmin() argmax = mi.argmax() f_print_info(f" argmin: {argmin}") f_print_info(f" argmax: {argmax}") # Verify we get integer indices ctx.assert_true(isinstance(argmin, int), "argmin: returns int") ctx.assert_true(isinstance(argmax, int), "argmax: returns int") .. _example-multiindex-delete-41: .. dropdown:: delete (test_multiindex.py:483) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 473 :emphasize-lines: 11 ctx.assert_equal(('b', 'two'), mi_inserted[1], "insert: inserted element") def test_delete(): """Test delete method""" f_print_info("Testing delete method...") arrays = [['a', 'b', 'c'], ['one', 'two', 'three']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_deleted = mi.delete(1) ctx.assert_equal(2, mi_deleted.size, "delete: size") ctx.assert_equal(('a', 'one'), mi_deleted[0], "delete: first element") ctx.assert_equal(('c', 'three'), mi_deleted[1], "delete: second element") def test_sort_values(): """Test sort_values method""" f_print_info("Testing sort_values method...") arrays = [['c', 'a', 'b'], ['three', 'one', 'two']] .. _example-multiindex-factorize-42: .. dropdown:: factorize (test_signature_phase14.py:52) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 42 :emphasize-lines: 11 # Should accept keep as keyword-only result = mi.drop_duplicates(keep='first') assert result is not None, "drop_duplicates should return result" print(" drop_duplicates: OK") def test_factorize(): """Test factorize has use_na_sentinel parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept use_na_sentinel codes, uniques = mi.factorize(sort=False, use_na_sentinel=True) assert codes is not None, "factorize should return codes" print(" factorize: OK") def test_format(): """Test format has formatter and other parameters""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept formatter, na_rep, names, space, sparsify, adjoin result = mi.format(name=None, formatter=None, na_rep=None, names=False, space=2, sparsify=None, adjoin=True) assert result is not None, "format should return result" .. _example-multiindex-format-43: .. dropdown:: format (test_signature_phase14.py:61) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 51 :emphasize-lines: 11 # Should accept use_na_sentinel codes, uniques = mi.factorize(sort=False, use_na_sentinel=True) assert codes is not None, "factorize should return codes" print(" factorize: OK") def test_format(): """Test format has formatter and other parameters""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept formatter, na_rep, names, space, sparsify, adjoin result = mi.format(name=None, formatter=None, na_rep=None, names=False, space=2, sparsify=None, adjoin=True) assert result is not None, "format should return result" print(" format: OK") def test_from_frame(): """Test from_frame has sortorder parameter""" df = {'a': ['x', 'y'], 'b': ['1', '2']} # Should accept sortorder mi = pandasCore.MultiIndex.from_frame(df, sortorder=None, names=None) assert mi is not None, "from_frame should return MultiIndex" .. _example-multiindex-get_level_values-44: .. dropdown:: get_level_values (test_multiindex.py:200) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 190 :emphasize-lines: 11 # ============================================================================= def test_get_level_values(): """Test get_level_values method""" f_print_info("Testing get_level_values method...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) # Get by index level0_vals = mi.get_level_values(0) ctx.assert_list_equal(['a', 'a', 'b', 'b'], level0_vals, "get_level_values: level 0 by index") level1_vals = mi.get_level_values(1) ctx.assert_list_equal(['one', 'two', 'one', 'two'], level1_vals, "get_level_values: level 1 by index") # Get by name level_by_name = mi.get_level_values('first') ctx.assert_list_equal(['a', 'a', 'b', 'b'], level_by_name, "get_level_values: level by name") .. _example-multiindex-get_loc-45: .. dropdown:: get_loc (test_multiindex.py:428) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 418 :emphasize-lines: 11 # ============================================================================= def test_get_loc(): """Test get_loc method""" f_print_info("Testing get_loc method...") arrays = [['a', 'a', 'b', 'b'], ['one', 'two', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) # Get location of specific tuple loc = mi.get_loc(('a', 'one')) ctx.assert_equal(0, loc, "get_loc: (a, one)") loc2 = mi.get_loc(('b', 'two')) ctx.assert_equal(3, loc2, "get_loc: (b, two)") def test_contains(): """Test contains method""" f_print_info("Testing contains method...") .. _example-multiindex-memory_usage-46: .. dropdown:: memory_usage (test_multiindex.py:635) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 625 :emphasize-lines: 11 ctx.assert_equal(('a', 'one'), result[0], "tolist: first tuple") def test_memory_usage(): """Test memory_usage method""" f_print_info("Testing memory_usage method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) mem = mi.memory_usage() ctx.assert_true(mem > 0, "memory_usage: positive value") # ============================================================================= # Magic Methods Tests # ============================================================================= def test_magic_methods(): """Test magic methods (__len__, __getitem__, __contains__, __iter__)""" f_print_info("Testing magic methods...") .. _example-multiindex-ravel-47: .. dropdown:: ravel (test_signature_phase14.py:150) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 140 :emphasize-lines: 11 # Should accept dropna result = mi.nunique(dropna=True) assert result is not None, "nunique should return result" print(" nunique: OK") def test_ravel(): """Test ravel has order parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept order result = mi.ravel(order='C') assert result is not None, "ravel should return result" print(" ravel: OK") def test_rename(): """Test rename has level parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) # Should accept level result = mi.rename(['new_x', 'new_y'], level=None, inplace=False) assert result is not None, "rename should return result" .. _example-multiindex-repeat-48: .. dropdown:: repeat (test_multiindex.py:610) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 600 :emphasize-lines: 11 ctx.assert_false(mi1.equals(mi3), "equals: different MultiIndex") def test_repeat(): """Test repeat method""" f_print_info("Testing repeat method...") arrays = [['a', 'b'], ['one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays) mi_repeated = mi.repeat(2) ctx.assert_equal(4, mi_repeated.size, "repeat: size doubled") ctx.assert_equal(mi[0], mi_repeated[0], "repeat: first element") ctx.assert_equal(mi[0], mi_repeated[1], "repeat: repeated first element") def test_tolist(): """Test tolist method""" f_print_info("Testing tolist method...") arrays = [['a', 'b'], ['one', 'two']] .. _example-multiindex-slice_indexer-49: .. dropdown:: slice_indexer (test_signature_phase14.py:177) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 167 :emphasize-lines: 11 # Should accept axis result = mi.repeat(2, axis=None) assert result is not None, "repeat should return result" print(" repeat: OK") def test_slice_indexer(): """Test slice_indexer has step parameter""" mi = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2'), ('c', '3')], names=['x', 'y']) # Should accept step result = mi.slice_indexer(start=None, end=None, step=None) assert result is not None, "slice_indexer should return result" print(" slice_indexer: OK") def test_symmetric_difference(): """Test symmetric_difference has result_name and sort parameters""" mi1 = pandasCore.MultiIndex.from_tuples([('a', '1'), ('b', '2')], names=['x', 'y']) mi2 = pandasCore.MultiIndex.from_tuples([('a', '1'), ('c', '3')], names=['x', 'y']) # Should accept result_name and sort result = mi1.symmetric_difference(mi2, result_name=None, sort=None) .. _example-multiindex-sortlevel-50: .. dropdown:: sortlevel (test_multiindex.py:286) :class-title: example-dropdown .. code-block:: python :linenos: :lineno-start: 276 :emphasize-lines: 11 ctx.assert_true('first' in frame or 'level_0' in frame, "to_frame: has column") def test_sortlevel(): """Test sortlevel method""" f_print_info("Testing sortlevel method...") arrays = [['b', 'a', 'b', 'a'], ['two', 'one', 'one', 'two']] mi = pandasCore.MultiIndex.from_arrays(arrays, names=['first', 'second']) sorted_mi, indices = mi.sortlevel(0) first_level_vals = sorted_mi.get_level_values(0) # After sorting by level 0, 'a' values should come first ctx.assert_equal('a', first_level_vals[0], "sortlevel: first value after sort") # ============================================================================= # Statistics Methods Tests # =============================================================================