MultiIndex ========== .. cpp:class:: pandas::MultiIndex Index class for axis labels in pandas data structures. Example ------- .. code-block:: cpp #include using namespace pandas; // Create MultiIndex MultiIndex idx({1, 2, 3}, "my_index"); size_t len = idx.size(); Constructors ------------ .. list-table:: :widths: 55 25 20 :header-rows: 1 * - Signature - Location - Example * - ``MultiIndex(std::vector>&& levels, std::vector>&& codes, std::vector> names = {}, bool verify_integrity = true)`` - pd_multiindex.h:88 - :ref:`View ` * - ``MultiIndex(const MultiIndex& other)`` - pd_multiindex.h:125 - :ref:`View ` * - ``MultiIndex(MultiIndex&& other) noexcept = default`` - pd_multiindex.h:149 - :ref:`View ` Construction ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static MultiIndex from_arrays(const std::vector>& arrays, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:186 - :ref:`View ` * - ``static MultiIndex from_arrays(std::initializer_list> arrays, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:240 - :ref:`View ` * - ``static MultiIndex from_arrays(const std::vector& arr1, const std::vector& arr2, std::initializer_list names)`` - MultiIndex - pd_multiindex.h:256 - :ref:`View ` * - ``static MultiIndex from_frame(const std::vector>& df, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:1805 - :ref:`View ` * - ``static MultiIndex from_mixed_arrays( const std::vector>& int_arrays, const std::vector>& str_arrays, const std::string& level_types, const std::vector>& names = {})`` - static MultiIndex - pd_multiindex.h:278 - :ref:`View ` * - ``static MultiIndex from_product(const std::vector>& iterables, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:420 - :ref:`View ` * - ``static MultiIndex from_product(std::initializer_list> iterables, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:470 - :ref:`View ` * - ``static MultiIndex from_tuples(const std::vector>& tuples, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:373 - :ref:`View ` * - ``static MultiIndex from_tuples(std::initializer_list> tuples, const std::vector>& names = {}, const std::optional& sortorder = std::nullopt)`` - MultiIndex - pd_multiindex.h:406 - :ref:`View ` Indexing / Selection -------------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::NDArray get_indexer(const MultiIndex& target, const std::string& method = "", std::optional limit = std::nullopt, std::optional tolerance = std::nullopt) const`` - numpy::NDArray - pd_multiindex.h:922 - :ref:`View ` * - ``numpy::NDArray get_indexer_for(const MultiIndex& target) const`` - numpy::NDArray - pd_multiindex.h:1817 - :ref:`View ` * - ``get_indexer_non_unique(const MultiIndex& target) const`` - - pd_multiindex.h:1827 - :ref:`View ` * - ``const IndexBase& get_level(size_t level) const`` - const IndexBase& - pd_multiindex.h:688 - :ref:`View ` * - ``const std::vector& get_level_categories(size_t level) const`` - const std::vector& - pd_multiindex.h:559 - * - ``std::unique_ptr get_level_values(int level) const`` - std::unique_ptr - pd_multiindex.h:614 - :ref:`View ` * - ``std::unique_ptr get_level_values(const std::string& level_name) const`` - std::unique_ptr - pd_multiindex.h:643 - :ref:`View ` * - ``std::vector get_level_values_str(size_t level) const`` - std::vector - pd_multiindex.h:666 - :ref:`View ` * - ``Index get_level_values_typed(size_t level) const`` - Index - pd_multiindex.h:1857 - * - ``std::variant> get_loc(const std::vector& key) const`` - std::variant> - pd_multiindex.h:882 - :ref:`View ` * - ``std::pair, MultiIndex> get_loc_level( const std::string& key, size_t level = 0, bool drop_level = true) const`` - std::pair, MultiIndex> - pd_multiindex.h:1886 - :ref:`View ` * - ``std::optional get_loc_string(const std::string& key) const`` - std::optional - pd_multiindex.h:3263 - :ref:`View ` * - ``numpy::NDArray get_locs(const std::vector>& seq) const`` - numpy::NDArray - pd_multiindex.h:1916 - :ref:`View ` * - ``std::optional get_name(size_t level) const`` - std::optional - pd_multiindex.h:698 - :ref:`View ` * - ``size_t get_slice_bound(const std::vector& label, const std::string& side) const`` - size_t - pd_multiindex.h:1944 - :ref:`View ` * - ``std::string get_string(size_t i) const`` - std::string - pd_multiindex.h:1083 - :ref:`View ` * - ``std::vector get_tuple_str(size_t index) const`` - std::vector - pd_multiindex.h:955 - :ref:`View ` * - ``std::pair> take( const std::vector& indices, int axis = 0, bool allow_fill = false, std::nullptr_t fill_value = nullptr) const`` - std::pair> - pd_multiindex.h:1193 - :ref:`View ` * - ``MultiIndex where(const numpy::NDArray& cond, const std::vector& other) const`` - MultiIndex - pd_multiindex.h:3075 - :ref:`View ` Data Manipulation ----------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``MultiIndex drop(const std::vector>& labels, std::optional> codes = std::nullopt, std::optional level = std::nullopt, const std::string& errors = "raise") const`` - MultiIndex - pd_multiindex.h:1509 - :ref:`View ` * - ``MultiIndex drop_duplicates(const std::string& keep = "first") const`` - MultiIndex - pd_multiindex.h:1545 - :ref:`View ` * - ``MultiIndex droplevel(size_t level) const`` - MultiIndex - pd_multiindex.h:743 - :ref:`View ` * - ``MultiIndex dropna(const std::string& how = "any") const`` - MultiIndex - pd_multiindex.h:1597 - :ref:`View ` * - ``MultiIndex insert(size_t loc, const std::vector& item) const`` - MultiIndex - pd_multiindex.h:2020 - :ref:`View ` * - ``reindex(const MultiIndex& target, const std::string& method = "", std::optional level = std::nullopt, std::optional limit = std::nullopt, std::optional tolerance = std::nullopt) const`` - - pd_multiindex.h:2521 - :ref:`View ` * - ``MultiIndex rename(const std::vector>& new_names, std::optional level = std::nullopt, bool inplace = false, const std::optional>& names = std::nullopt) const`` - MultiIndex - pd_multiindex.h:2543 - :ref:`View ` * - ``MultiIndex reorder_levels(const std::vector& order) const`` - MultiIndex - pd_multiindex.h:801 - :ref:`View ` * - ``MultiIndex set_names(const std::vector>& names, std::optional level = std::nullopt, bool inplace = false) const`` - MultiIndex - pd_multiindex.h:716 - :ref:`View ` * - ``MultiIndex swaplevel(size_t i, size_t j) const`` - MultiIndex - pd_multiindex.h:771 - :ref:`View ` Missing Data ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``MultiIndex fillna(const std::vector& value, const std::string& downcast = "") const`` - MultiIndex - pd_multiindex.h:1734 - :ref:`View ` * - ``numpy::NDArray isna() const`` - numpy::NDArray - pd_multiindex.h:2218 - :ref:`View ` * - ``numpy::NDArray isnull() const`` - numpy::NDArray - pd_multiindex.h:2229 - :ref:`View ` * - ``numpy::NDArray notna() const`` - numpy::NDArray - pd_multiindex.h:2445 - :ref:`View ` * - ``numpy::NDArray notnull() const`` - numpy::NDArray - pd_multiindex.h:2456 - :ref:`View ` Statistics ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector max() const`` - std::vector - pd_multiindex.h:2390 - :ref:`View ` * - ``std::vector min() const`` - std::vector - pd_multiindex.h:2434 - :ref:`View ` * - ``size_t nunique() const`` - size_t - pd_multiindex.h:2463 - :ref:`View ` Aggregation ----------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``groupby(const std::vector& values) const`` - - pd_multiindex.h:1970 - :ref:`View ` * - ``MultiIndex map(Func mapper, const std::string& na_action = "") const`` - MultiIndex - pd_multiindex.h:2372 - :ref:`View ` Comparison ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``int compare_tuples(size_t idx_a, size_t idx_b) const`` - int - pd_multiindex.h:3151 - * - ``bool equal_levels(const MultiIndex& other) const`` - bool - pd_multiindex.h:1650 - :ref:`View ` * - ``bool equals(const MultiIndex& other) const`` - bool - pd_multiindex.h:1674 - :ref:`View ` * - ``const std::vector>& levels() const`` - const std::vector>& - pd_multiindex.h:520 - :ref:`View ` * - ``std::vector levshape() const`` - std::vector - pd_multiindex.h:491 - :ref:`View ` Sorting ------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::NDArray argsort() const`` - numpy::NDArray - pd_multiindex.h:1153 - :ref:`View ` * - ``size_t searchsorted(const std::vector& value, const std::string& side = "left", const std::optional>& sorter = std::nullopt) const`` - size_t - pd_multiindex.h:2605 - :ref:`View ` * - ``MultiIndex sort_values(bool ascending = true, const std::string& na_position = "last", bool return_indexer = false, std::nullptr_t key = nullptr) const`` - MultiIndex - pd_multiindex.h:2758 - :ref:`View ` Reshaping --------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::map> to_frame(bool index = true, bool allow_duplicates = false, const std::optional>& name = std::nullopt) const`` - std::map> - pd_multiindex.h:2838 - :ref:`View ` * - ``MultiIndex transpose(bool copy_data = false) const`` - MultiIndex - pd_multiindex.h:2902 - :ref:`View ` Combining --------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``MultiIndex append(const MultiIndex& other) const`` - MultiIndex - pd_multiindex.h:1234 - :ref:`View ` * - ``join(const MultiIndex& other, const std::string& how = "left", std::optional level = std::nullopt, bool return_indexers = true, bool sort = false) const`` - - pd_multiindex.h:2254 - :ref:`View ` Time Series ----------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::optional> asof(const std::vector& key, const std::optional>& label = std::nullopt) const`` - std::optional> - pd_multiindex.h:1329 - :ref:`View ` * - ``numpy::NDArray asof_locs( const std::vector>& where, const numpy::NDArray& mask) const`` - numpy::NDArray - pd_multiindex.h:1359 - :ref:`View ` * - ``std::vector> diff(int periods = 1) const`` - std::vector> - pd_multiindex.h:1449 - :ref:`View ` * - ``MultiIndex difference(const MultiIndex& other, bool sort = true) const`` - MultiIndex - pd_multiindex.h:1473 - :ref:`View ` * - ``MultiIndex shift(int periods = 1, const std::optional& freq = std::nullopt) const`` - MultiIndex - pd_multiindex.h:2692 - :ref:`View ` I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector> to_flat_index() const`` - std::vector> - pd_multiindex.h:985 - :ref:`View ` * - ``std::vector> to_list() const`` - std::vector> - pd_multiindex.h:2858 - :ref:`View ` * - ``std::vector> to_numpy() const`` - std::vector> - pd_multiindex.h:2866 - :ref:`View ` * - ``std::string to_string() const`` - std::string - pd_multiindex.h:999 - :ref:`View ` * - ``std::vector> tolist() const`` - std::vector> - pd_multiindex.h:2893 - :ref:`View ` Conversion ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``MultiIndex astype(const std::string& dtype, bool copy = true) const`` - MultiIndex - pd_multiindex.h:1393 - :ref:`View ` * - ``MultiIndex copy() const`` - MultiIndex - pd_multiindex.h:1264 - :ref:`View ` * - ``MultiIndex infer_objects() const`` - MultiIndex - pd_multiindex.h:2010 - :ref:`View ` * - ``MultiIndex view() const`` - MultiIndex - pd_multiindex.h:3065 - :ref:`View ` Set Operations -------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::NDArray duplicated(const std::string& keep = "first") const`` - numpy::NDArray - pd_multiindex.h:1607 - :ref:`View ` * - ``MultiIndex intersection(const MultiIndex& other, bool sort = false) const`` - MultiIndex - pd_multiindex.h:2060 - :ref:`View ` * - ``numpy::NDArray isin(const std::vector>& values, std::optional level = std::nullopt) const`` - numpy::NDArray - pd_multiindex.h:2171 - :ref:`View ` * - ``MultiIndex symmetric_difference(const MultiIndex& other, const std::optional& result_name = std::nullopt, bool sort = true) const`` - MultiIndex - pd_multiindex.h:2789 - :ref:`View ` * - ``MultiIndex union_(const MultiIndex& other, bool sort = true) const`` - MultiIndex - pd_multiindex.h:2939 - :ref:`View ` * - ``MultiIndex unique(std::optional level = std::nullopt) const`` - MultiIndex - pd_multiindex.h:2983 - :ref:`View ` Type Checking ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``bool is_(const MultiIndex& other) const`` - bool - pd_multiindex.h:2096 - :ref:`View ` * - ``bool is_boolean() const`` - bool - pd_multiindex.h:2103 - :ref:`View ` * - ``bool is_categorical() const`` - bool - pd_multiindex.h:2110 - :ref:`View ` * - ``bool is_floating() const`` - bool - pd_multiindex.h:2117 - :ref:`View ` * - ``bool is_integer() const`` - bool - pd_multiindex.h:2129 - :ref:`View ` * - ``bool is_interval() const`` - bool - pd_multiindex.h:2142 - :ref:`View ` * - ``bool is_level_ordered(size_t level) const`` - bool - pd_multiindex.h:568 - * - ``bool is_monotonic_decreasing() const`` - bool - pd_multiindex.h:3122 - :ref:`View ` * - ``bool is_monotonic_increasing() const`` - bool - pd_multiindex.h:3108 - :ref:`View ` * - ``bool is_numeric() const`` - bool - pd_multiindex.h:2149 - :ref:`View ` * - ``bool is_object() const`` - bool - pd_multiindex.h:2156 - :ref:`View ` * - ``bool is_unique() const`` - bool - pd_multiindex.h:575 - :ref:`View ` Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``bool all() const`` - bool - pd_multiindex.h:1276 - :ref:`View ` * - ``bool any() const`` - bool - pd_multiindex.h:1285 - :ref:`View ` * - ``size_t argmax() const`` - size_t - pd_multiindex.h:1292 - :ref:`View ` * - ``size_t argmin() const`` - size_t - pd_multiindex.h:1309 - :ref:`View ` * - ``std::vector> arrays(nlevels)`` - std::vector> - pd_multiindex.h:385 - :ref:`View ` * - ``std::vector> arrays(nlevels)`` - std::vector> - pd_multiindex.h:441 - :ref:`View ` * - ``std::vector> arrays(nlevels())`` - std::vector> - pd_multiindex.h:1243 - :ref:`View ` * - ``std::vector> arrays(nlevels())`` - std::vector> - pd_multiindex.h:2028 - :ref:`View ` * - ``void build_hash_table() const`` - void - pd_multiindex.h:3189 - * - ``const std::vector>& codes() const`` - const std::vector>& - pd_multiindex.h:527 - :ref:`View ` * - ``bool contains(const std::vector& key) const`` - bool - pd_multiindex.h:904 - :ref:`View ` * - ``MultiIndex delete_(size_t loc) const`` - MultiIndex - pd_multiindex.h:1409 - :ref:`View ` * - ``MultiIndex delete_(const std::vector& locs) const`` - MultiIndex - pd_multiindex.h:1430 - :ref:`View ` * - ``std::vector dtypes() const`` - std::vector - pd_multiindex.h:3137 - :ref:`View ` * - ``bool empty() const`` - bool - pd_multiindex.h:513 - :ref:`View ` * - ``void ensure_hash_table() const`` - void - pd_multiindex.h:3203 - * - ``std::pair, MultiIndex> factorize(bool sort = false, bool use_na_sentinel = true) const`` - std::pair, MultiIndex> - pd_multiindex.h:1702 - :ref:`View ` * - ``std::vector format(bool name = true, size_t max_seq_items = 100, bool adjoin = true, std::nullptr_t formatter = nullptr, const std::string& na_rep = "NaN", std::nullptr_t names = nullptr, int space = 1, bool sparsify = true) const`` - std::vector - pd_multiindex.h:1753 - :ref:`View ` * - ``bool has_duplicates() const`` - bool - pd_multiindex.h:593 - :ref:`View ` * - ``bool has_level_categories(size_t level) const`` - bool - pd_multiindex.h:552 - * - ``bool holds_integer() const`` - bool - pd_multiindex.h:1988 - :ref:`View ` * - ``bool identical(const MultiIndex& other) const`` - bool - pd_multiindex.h:2002 - :ref:`View ` * - ``void invalidate_caches() const`` - void - pd_multiindex.h:3237 - * - ``std::vector item() const`` - std::vector - pd_multiindex.h:2237 - :ref:`View ` * - ``static std::string make_tuple_key(const std::vector& values)`` - static std::string - pd_multiindex.h:3212 - * - ``std::string make_tuple_key_at(size_t index) const`` - std::string - pd_multiindex.h:3224 - * - ``size_t memory_usage(bool deep = false) const`` - size_t - pd_multiindex.h:2402 - :ref:`View ` * - ``const std::vector>& names() const`` - const std::vector>& - pd_multiindex.h:534 - :ref:`View ` * - ``size_t nlevels() const`` - size_t - pd_multiindex.h:484 - :ref:`View ` * - ``std::vector> pairs(counts.begin(), counts.end())`` - std::vector> - pd_multiindex.h:3040 - :ref:`View ` * - ``MultiIndex putmask(const numpy::NDArray& mask, const std::vector& value) const`` - MultiIndex - pd_multiindex.h:2474 - :ref:`View ` * - ``std::vector> ravel() const`` - std::vector> - pd_multiindex.h:2507 - :ref:`View ` * - ``MultiIndex remove_unused_levels() const`` - MultiIndex - pd_multiindex.h:835 - :ref:`View ` * - ``MultiIndex repeat(size_t repeats, const std::optional& axis = std::nullopt) const`` - MultiIndex - pd_multiindex.h:2568 - :ref:`View ` * - ``std::string repr() const`` - std::string - pd_multiindex.h:1067 - :ref:`View ` * - ``MultiIndex result(\*this)`` - MultiIndex - pd_multiindex.h:721 - :ref:`View ` * - ``std::vector> result(size())`` - std::vector> - pd_multiindex.h:1450 - :ref:`View ` * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:1476 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:1522 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2063 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2263 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2374 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2483 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2571 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2794 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:2942 - * - ``std::vector> result_arrays(nlevels())`` - std::vector> - pd_multiindex.h:3084 - * - ``MultiIndex round(int decimals = 0) const`` - MultiIndex - pd_multiindex.h:2593 - :ref:`View ` * - ``MultiIndex set_codes(const std::vector>& codes, std::optional level = std::nullopt, bool verify_integrity = true) const`` - MultiIndex - pd_multiindex.h:2619 - :ref:`View ` * - ``void set_level_categories(size_t level, const std::vector& categories, bool ordered = false)`` - void - pd_multiindex.h:541 - * - ``MultiIndex set_levels(const std::vector>& levels, std::optional level = std::nullopt, bool verify_integrity = true) const`` - MultiIndex - pd_multiindex.h:2655 - :ref:`View ` * - ``size_t size() const`` - size_t - pd_multiindex.h:503 - :ref:`View ` * - ``std::pair slice_indexer( const std::optional>& start = std::nullopt, const std::optional>& end = std::nullopt, size_t step = 1) const`` - std::pair - pd_multiindex.h:2706 - :ref:`View ` * - ``std::pair slice_locs( const std::optional>& start = std::nullopt, const std::optional>& end = std::nullopt, size_t step = 1) const`` - std::pair - pd_multiindex.h:2732 - :ref:`View ` * - ``MultiIndex sort(bool ascending = true) const`` - MultiIndex - pd_multiindex.h:2746 - :ref:`View ` * - ``std::pair> sortlevel( size_t level = 0, bool ascending = true, const std::string& na_position = "last", bool sort_remaining = true) const`` - std::pair> - pd_multiindex.h:1118 - :ref:`View ` * - ``StringMethods str() const`` - StringMethods - pd_multiindex.h:1102 - :ref:`View ` * - ``MultiIndex temp(other)`` - MultiIndex - pd_multiindex.h:156 - * - ``MultiIndex truncate( const std::optional>& before = std::nullopt, const std::optional>& after = std::nullopt) const`` - MultiIndex - pd_multiindex.h:2915 - :ref:`View ` * - ``void verify_integrity_impl() const`` - void - pd_multiindex.h:3172 - Code Examples ------------- The following examples are extracted from the test suite. .. _example-multiindex-multiindex-0: .. dropdown:: MultiIndex (pd_test_3_all.cpp:26015) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 26005 :emphasize-lines: 11 // Level 0 (rows): unique rows {0,1,2} = 3 labels if (mi.get_level(0).size() != 3) throw std::runtime_error("Expected 3 row labels, got " + std::to_string(mi.get_level(0).size())); // Level 1 (cols): unique cols {0,1,2} = 3 labels if (mi.get_level(1).size() != 3) throw std::runtime_error("Expected 3 col labels, got " + std::to_string(mi.get_level(1).size())); std::cout << " PASSED" << std::endl; } int pd_test_sparse_coo_main() { try { std::cout << "========= Sparse COO MultiIndex (N1) ==================" << std::endl; pd_test_sparse_coo_non_dense(); pd_test_sparse_coo_dense(); pd_test_sparse_coo_empty(); pd_test_sparse_coo_sorting(); pd_test_sparse_coo_multiindex_levels(); std::cout << "All pd_test_sparse_coo tests passed!" << std::endl; return 0; } catch (const std::exception& e) { std::cout << "FAILED: " << e.what() << std::endl; return 1; .. _example-multiindex-multiindex-1: .. dropdown:: MultiIndex (pd_test_3_all.cpp:26015) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 26005 :emphasize-lines: 11 // Level 0 (rows): unique rows {0,1,2} = 3 labels if (mi.get_level(0).size() != 3) throw std::runtime_error("Expected 3 row labels, got " + std::to_string(mi.get_level(0).size())); // Level 1 (cols): unique cols {0,1,2} = 3 labels if (mi.get_level(1).size() != 3) throw std::runtime_error("Expected 3 col labels, got " + std::to_string(mi.get_level(1).size())); std::cout << " PASSED" << std::endl; } int pd_test_sparse_coo_main() { try { std::cout << "========= Sparse COO MultiIndex (N1) ==================" << std::endl; pd_test_sparse_coo_non_dense(); pd_test_sparse_coo_dense(); pd_test_sparse_coo_empty(); pd_test_sparse_coo_sorting(); pd_test_sparse_coo_multiindex_levels(); std::cout << "All pd_test_sparse_coo tests passed!" << std::endl; return 0; } catch (const std::exception& e) { std::cout << "FAILED: " << e.what() << std::endl; return 1; .. _example-multiindex-multiindex-2: .. dropdown:: MultiIndex (pd_test_3_all.cpp:26015) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 26005 :emphasize-lines: 11 // Level 0 (rows): unique rows {0,1,2} = 3 labels if (mi.get_level(0).size() != 3) throw std::runtime_error("Expected 3 row labels, got " + std::to_string(mi.get_level(0).size())); // Level 1 (cols): unique cols {0,1,2} = 3 labels if (mi.get_level(1).size() != 3) throw std::runtime_error("Expected 3 col labels, got " + std::to_string(mi.get_level(1).size())); std::cout << " PASSED" << std::endl; } int pd_test_sparse_coo_main() { try { std::cout << "========= Sparse COO MultiIndex (N1) ==================" << std::endl; pd_test_sparse_coo_non_dense(); pd_test_sparse_coo_dense(); pd_test_sparse_coo_empty(); pd_test_sparse_coo_sorting(); pd_test_sparse_coo_multiindex_levels(); std::cout << "All pd_test_sparse_coo tests passed!" << std::endl; return 0; } catch (const std::exception& e) { std::cout << "FAILED: " << e.what() << std::endl; return 1; .. _example-multiindex-from_arrays-3: .. dropdown:: from_arrays (pd_test_1_all.cpp:1994) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1984 :emphasize-lines: 11 // ============================================================================ // Test: from_arrays factory method // ============================================================================ void test_from_arrays() { std::cout << "========= IntervalArray: from_arrays ======================= "; std::vector left_vec = {0, 10, 20}; std::vector right_vec = {5, 15, 25}; auto arr = pandas::IntervalArrayInt64::from_arrays(left_vec, right_vec); if (arr.size() != 3) { std::cout << "[FAIL] : in test_from_arrays() : size" << std::endl; return; } auto interval1 = arr[1]; if (!interval1.has_value() || interval1->first != 10 || interval1->second != 15) { std::cout << "[FAIL] : in test_from_arrays() : interval values" << std::endl; return; .. _example-multiindex-from_arrays-4: .. dropdown:: from_arrays (pd_test_1_all.cpp:1994) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1984 :emphasize-lines: 11 // ============================================================================ // Test: from_arrays factory method // ============================================================================ void test_from_arrays() { std::cout << "========= IntervalArray: from_arrays ======================= "; std::vector left_vec = {0, 10, 20}; std::vector right_vec = {5, 15, 25}; auto arr = pandas::IntervalArrayInt64::from_arrays(left_vec, right_vec); if (arr.size() != 3) { std::cout << "[FAIL] : in test_from_arrays() : size" << std::endl; return; } auto interval1 = arr[1]; if (!interval1.has_value() || interval1->first != 10 || interval1->second != 15) { std::cout << "[FAIL] : in test_from_arrays() : interval values" << std::endl; return; .. _example-multiindex-from_arrays-5: .. dropdown:: from_arrays (pd_test_1_all.cpp:1994) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1984 :emphasize-lines: 11 // ============================================================================ // Test: from_arrays factory method // ============================================================================ void test_from_arrays() { std::cout << "========= IntervalArray: from_arrays ======================= "; std::vector left_vec = {0, 10, 20}; std::vector right_vec = {5, 15, 25}; auto arr = pandas::IntervalArrayInt64::from_arrays(left_vec, right_vec); if (arr.size() != 3) { std::cout << "[FAIL] : in test_from_arrays() : size" << std::endl; return; } auto interval1 = arr[1]; if (!interval1.has_value() || interval1->first != 10 || interval1->second != 15) { std::cout << "[FAIL] : in test_from_arrays() : interval values" << std::endl; return; .. _example-multiindex-from_frame-6: .. dropdown:: from_frame (pd_test_3_all.cpp:9009) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 8999 :emphasize-lines: 11 bool neq = mi1.equal_levels(mi3); if (neq) { std::cout << " [FAIL] : in pd_test_3_all_multiindex_equal_levels() : different levels should not be equal" << std::endl; throw std::runtime_error("pd_test_3_all_multiindex_equal_levels failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_multiindex_from_frame() { std::cout << "========= MultiIndex.from_frame() ================="; std::vector> columns = { {"a", "a", "b", "b"}, {"x", "y", "x", "y"} }; std::vector> names = {"level0", "level1"}; pandas::MultiIndex mi = pandas::MultiIndex::from_frame(columns, names); if (mi.size() != 4) { .. _example-multiindex-from_mixed_arrays-7: .. dropdown:: from_mixed_arrays (pd_test_1_all.cpp:14830) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14820 :emphasize-lines: 11 void pd_test_multiindex_mixed_types() { std::cout << "========= mixed types (int64 + string) ================ "; std::vector> int_arrays = { {2020, 2020, 2021, 2021} }; std::vector> str_arrays = { {"Q1", "Q2", "Q1", "Q2"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_mixed_arrays( int_arrays, str_arrays, "is", {std::optional("year"), std::optional("quarter")} ); bool passed = true; if (mi.nlevels() != 2) { std::cout << " [FAIL] : nlevels should be 2" << std::endl; passed = false; } .. _example-multiindex-from_product-8: .. dropdown:: from_product (pd_test_1_all.cpp:14246) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14236 :emphasize-lines: 11 } void pd_test_multiindex_from_product() { std::cout << "========= from_product ================================ "; std::vector> iterables = { {"a", "b"}, {"1", "2", "3"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_product(iterables); bool passed = true; // Should have 2*3=6 entries if (mi.size() != 6) { std::cout << " [FAIL] : size should be 6, got " << mi.size() << std::endl; passed = false; } // Check order: (a,1), (a,2), (a,3), (b,1), (b,2), (b,3) .. _example-multiindex-from_product-9: .. dropdown:: from_product (pd_test_1_all.cpp:14246) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14236 :emphasize-lines: 11 } void pd_test_multiindex_from_product() { std::cout << "========= from_product ================================ "; std::vector> iterables = { {"a", "b"}, {"1", "2", "3"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_product(iterables); bool passed = true; // Should have 2*3=6 entries if (mi.size() != 6) { std::cout << " [FAIL] : size should be 6, got " << mi.size() << std::endl; passed = false; } // Check order: (a,1), (a,2), (a,3), (b,1), (b,2), (b,3) .. _example-multiindex-from_tuples-10: .. dropdown:: from_tuples (pd_test_1_all.cpp:2022) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2012 :emphasize-lines: 11 // ============================================================================ void test_from_tuples() { std::cout << "========= IntervalArray: from_tuples ======================= "; std::vector> tuples = { {0.0, 1.5}, {1.5, 3.0}, {3.0, 4.5} }; auto arr = pandas::IntervalArrayFloat64::from_tuples(tuples); if (arr.size() != 3) { std::cout << "[FAIL] : in test_from_tuples() : size" << std::endl; return; } auto interval2 = arr[2]; if (!interval2.has_value() || interval2->first != 3.0 || interval2->second != 4.5) { std::cout << "[FAIL] : in test_from_tuples() : interval values" << std::endl; return; .. _example-multiindex-from_tuples-11: .. dropdown:: from_tuples (pd_test_1_all.cpp:2022) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2012 :emphasize-lines: 11 // ============================================================================ void test_from_tuples() { std::cout << "========= IntervalArray: from_tuples ======================= "; std::vector> tuples = { {0.0, 1.5}, {1.5, 3.0}, {3.0, 4.5} }; auto arr = pandas::IntervalArrayFloat64::from_tuples(tuples); if (arr.size() != 3) { std::cout << "[FAIL] : in test_from_tuples() : size" << std::endl; return; } auto interval2 = arr[2]; if (!interval2.has_value() || interval2->first != 3.0 || interval2->second != 4.5) { std::cout << "[FAIL] : in test_from_tuples() : interval values" << std::endl; return; .. _example-multiindex-get_indexer-12: .. dropdown:: get_indexer (pd_test_1_all.cpp:10332) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10322 :emphasize-lines: 11 void pd_test_extension_index_get_indexer() { std::cout << "========= get_indexer ========================="; pandas::CategoricalArray arr1({"a", "b", "c", "d"}); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"b", "d", "x"}); pandas::CategoricalIndex idx2(arr2); auto indexer = idx1.get_indexer(idx2); bool passed = (indexer.getSize() == 3 && indexer.getElementAt({0}) == 1 && indexer.getElementAt({1}) == 3 && indexer.getElementAt({2}) == -1); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_get_indexer() : get_indexer check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_get_indexer failed"); } .. _example-multiindex-get_indexer_for-13: .. dropdown:: get_indexer_for (pd_test_3_all.cpp:716) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 706 :emphasize-lines: 11 // ============================================================================ // Category 6: Index Indexer Methods // ============================================================================ void pd_test_3_all_index_indexers() { std::cout << "========= Index.get_indexer_for/non_unique/slice_indexer() "; std::vector vals = {"a", "b", "c", "d", "e"}; pandas::Index idx(vals); // Test get_indexer_for() std::vector target = {"b", "d", "f"}; // "f" doesn't exist numpy::NDArray indexer = idx.get_indexer_for(target); if (indexer.getSize() != 3) { std::cout << " [FAIL] : in pd_test_3_all_index_indexers() : get_indexer_for size mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_index_indexers failed: get_indexer_for size"); } // "b" is at index 1 if (indexer.getElementAt({0}) != 1) { std::cout << " [FAIL] : in pd_test_3_all_index_indexers() : 'b' should be at index 1" << std::endl; throw std::runtime_error("pd_test_3_all_index_indexers failed: 'b' index"); .. _example-multiindex-get_indexer_non_unique-14: .. dropdown:: get_indexer_non_unique (pd_test_3_all.cpp:739) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 729 :emphasize-lines: 11 if (indexer.getElementAt({1}) != 3) { std::cout << " [FAIL] : in pd_test_3_all_index_indexers() : 'd' should be at index 3" << std::endl; throw std::runtime_error("pd_test_3_all_index_indexers failed: 'd' index"); } // "f" doesn't exist -> -1 if (indexer.getElementAt({2}) != -1) { std::cout << " [FAIL] : in pd_test_3_all_index_indexers() : 'f' should be -1" << std::endl; throw std::runtime_error("pd_test_3_all_index_indexers failed: 'f' index"); } // Test get_indexer_non_unique() std::vector target2 = {"a", "c", "z"}; // "z" doesn't exist pandas::Index target_idx(target2); auto [indexer2, missing] = idx.get_indexer_non_unique(target_idx); if (indexer2.getSize() < 2) { std::cout << " [FAIL] : in pd_test_3_all_index_indexers() : get_indexer_non_unique size too small" << std::endl; throw std::runtime_error("pd_test_3_all_index_indexers failed: get_indexer_non_unique size"); } // Test slice_indexer() .. _example-multiindex-get_level-15: .. dropdown:: get_level (pd_test_3_all.cpp:26007) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25997 :emphasize-lines: 11 std::vector rows = {0, 1, 2}; std::vector cols = {1, 2, 0}; auto s = ::pandas::series_from_coo(data, rows, cols, 3, 3, false); if (!s.has_multiindex()) throw std::runtime_error("Expected MultiIndex"); const auto& mi = s.multiindex(); if (mi.nlevels() != 2) throw std::runtime_error("Expected 2 levels, got " + std::to_string(mi.nlevels())); // Level 0 (rows): unique rows {0,1,2} = 3 labels if (mi.get_level(0).size() != 3) throw std::runtime_error("Expected 3 row labels, got " + std::to_string(mi.get_level(0).size())); // Level 1 (cols): unique cols {0,1,2} = 3 labels if (mi.get_level(1).size() != 3) throw std::runtime_error("Expected 3 col labels, got " + std::to_string(mi.get_level(1).size())); std::cout << " PASSED" << std::endl; } int pd_test_sparse_coo_main() { try { std::cout << "========= Sparse COO MultiIndex (N1) ==================" << std::endl; pd_test_sparse_coo_non_dense(); pd_test_sparse_coo_dense(); .. _example-multiindex-get_level_values-16: .. dropdown:: get_level_values (pd_test_3_all.cpp:4524) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4514 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_interval_index_get_level_values_droplevel() { std::cout << "========= IntervalIndex.get_level_values/droplevel() "; pandas::IntervalIndex64 idx = pandas::IntervalIndex64::from_breaks({0, 10, 20, 30}); // get_level_values(0) should work pandas::IntervalIndex64 level_vals = idx.get_level_values(0); if (level_vals.size() != idx.size()) { throw std::runtime_error("get_level_values(0) size mismatch"); } // get_level_values(1) should throw bool threw = false; try { idx.get_level_values(1); } catch (const std::out_of_range&) { .. _example-multiindex-get_level_values-17: .. dropdown:: get_level_values (pd_test_3_all.cpp:4524) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4514 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_interval_index_get_level_values_droplevel() { std::cout << "========= IntervalIndex.get_level_values/droplevel() "; pandas::IntervalIndex64 idx = pandas::IntervalIndex64::from_breaks({0, 10, 20, 30}); // get_level_values(0) should work pandas::IntervalIndex64 level_vals = idx.get_level_values(0); if (level_vals.size() != idx.size()) { throw std::runtime_error("get_level_values(0) size mismatch"); } // get_level_values(1) should throw bool threw = false; try { idx.get_level_values(1); } catch (const std::out_of_range&) { .. _example-multiindex-get_level_values_str-18: .. dropdown:: get_level_values_str (pd_test_1_all.cpp:14394) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14384 :emphasize-lines: 11 void pd_test_multiindex_get_level_values() { std::cout << "========= get_level_values ============================ "; std::vector> arrays = { {"a", "a", "b"}, {"x", "y", "z"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); auto level0_vals = mi.get_level_values_str(0); auto level1_vals = mi.get_level_values_str(1); bool passed = true; if (level0_vals.size() != 3 || level0_vals[0] != "a" || level0_vals[1] != "a" || level0_vals[2] != "b") { std::cout << " [FAIL] : level 0 values mismatch" << std::endl; passed = false; } .. _example-multiindex-get_loc-19: .. dropdown:: get_loc (pd_test_1_all.cpp:10281) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10271 :emphasize-lines: 11 bool passed = (idx.contains("apple") && idx.contains("banana") && !idx.contains("grape")); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_contains() : contains check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_contains failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_get_loc_unique() { std::cout << "========= get_loc (unique) ========================="; pandas::CategoricalArray arr({"apple", "banana", "cherry"}); pandas::CategoricalIndex idx(arr); auto loc_apple = idx.get_loc("apple"); auto loc_banana = idx.get_loc("banana"); auto loc_cherry = idx.get_loc("cherry"); bool passed = (std::holds_alternative(loc_apple) && std::get(loc_apple) == 0 && std::get(loc_banana) == 1 && .. _example-multiindex-get_loc_level-20: .. dropdown:: get_loc_level (pd_test_3_all.cpp:9033) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9023 :emphasize-lines: 11 if (mi.nlevels() != 2) { std::cout << " [FAIL] : in pd_test_3_all_multiindex_from_frame() : nlevels mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_multiindex_from_frame failed: nlevels"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_multiindex_get_loc_level() { std::cout << "========= MultiIndex.get_loc_level() =============="; std::vector> arrays = { {"a", "a", "b", "b"}, {"1", "2", "1", "2"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); auto [locs, result_mi] = mi.get_loc_level("a", 0, true); if (locs.size() != 2) { .. _example-multiindex-get_loc_string-21: .. dropdown:: get_loc_string (pd_test_3_all.cpp:28108) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 28098 :emphasize-lines: 11 vals.push_back(numpy::timedelta64(ns, numpy::DateTimeUnit::Nanosecond)); } return pandas::TimedeltaArray(vals); } void pd_test_getitem_timedelta_str_lookup() { std::cout << " -- pd_test_getitem_timedelta_str_lookup --" << std::endl; int fail = 0; auto tda = ge_make_tda({1 * GE_NS_PER_DAY, 2 * GE_NS_PER_DAY, 3 * GE_NS_PER_DAY}); pandas::TimedeltaIndex tdi(tda); auto pos = tdi.get_loc_string("2 days"); if (!pos.has_value()) { std::cout << " FAIL: '2 days' not found" << std::endl; fail++; } else if (*pos != 1) { std::cout << " FAIL: expected pos=1, got " << *pos << std::endl; fail++; } if (fail == 0) std::cout << " OK" << std::endl; if (fail) throw std::runtime_error("pd_test_getitem_timedelta_str_lookup failed"); } void pd_test_getitem_timedelta_str_not_found() { std::cout << " -- pd_test_getitem_timedelta_str_not_found --" << std::endl; int fail = 0; auto tda = ge_make_tda({1 * GE_NS_PER_DAY}); .. _example-multiindex-get_locs-22: .. dropdown:: get_locs (pd_test_3_all.cpp:9057) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9047 :emphasize-lines: 11 if (locs[0] != 0 || locs[1] != 1) { std::cout << " [FAIL] : in pd_test_3_all_multiindex_get_loc_level() : wrong locations" << std::endl; throw std::runtime_error("pd_test_3_all_multiindex_get_loc_level failed: wrong locs"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_multiindex_get_locs() { std::cout << "========= MultiIndex.get_locs() ==================="; std::vector> arrays = { {"a", "a", "b", "b"}, {"1", "2", "1", "2"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); std::vector> seq = {{"a", "1"}, {"b", "2"}}; numpy::NDArray locs = mi.get_locs(seq); .. _example-multiindex-get_name-23: .. dropdown:: get_name (pd_test_5_all.cpp:50005) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 49995 :emphasize-lines: 11 std::cout << tag << " [" << c << "]" << " override=" << override_or_empty(df, c) << " dtype=" << series_dtype_or_missing(df, c) << "\n"; } std::cout << tag << " has_multiindex=" << df.has_multiindex() << "\n"; if (df.has_multiindex()) { const auto& mi = df.multiindex(); std::cout << tag << " mi.nlevels=" << mi.nlevels() << " mi.size=" << mi.size() << "\n"; for (size_t i = 0; i < mi.nlevels(); ++i) { auto nm = mi.get_name(i); std::cout << tag << " level[" << i << "] name=" << (nm.has_value() ? *nm : std::string("")) << " level_size=" << mi.get_level(i).size() << " level_dtype=" << mi.get_level(i).dtype_name() << "\n"; } } std::cout << tag << " to_string:\n" << df.to_string() << "\n"; } .. _example-multiindex-get_slice_bound-24: .. dropdown:: get_slice_bound (pd_test_3_all.cpp:3644) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3634 :emphasize-lines: 11 formatted = idx.format(custom_formatter); if (formatted[0] != "val:1") { throw std::runtime_error("custom formatter failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_index_get_slice_bound() { std::cout << "========= Index.get_slice_bound() =================="; pandas::Index idx({10, 20, 30, 40, 50}); // Exact match, left side size_t bound = idx.get_slice_bound(30, "left"); if (bound != 2) { throw std::runtime_error("left bound for 30 should be 2"); } // Exact match, right side .. _example-multiindex-get_string-25: .. dropdown:: get_string (pd_test_3_all.cpp:27746) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27736 :emphasize-lines: 11 } } pandas::Series si({10, 20, 30}, "ints"); auto result2 = si.astype("str"); auto* str_s2 = dynamic_cast*>(result2.get()); if (!str_s2) { std::cout << " FAIL: expected Series from int" << std::endl; fail++; } else { if (str_s2->get_string(0) != "10") { std::cout << " FAIL: expected '10', got '" << str_s2->get_string(0) << "'" << std::endl; fail++; } } if (fail == 0) std::cout << " OK" << std::endl; } void pd_test_astype_datetime_to_string() { std::cout << " -- pd_test_astype_datetime_to_string --" << std::endl; .. _example-multiindex-get_tuple_str-26: .. dropdown:: get_tuple_str (pd_test_3_all.cpp:1023) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1013 :emphasize-lines: 11 } for (size_t i = 0; i < bn.size(); ++i) { if (bn[i].value_or("") != nn[i].value_or("")) { std::cout << " [FAIL] level name " << i << " differs: '" << bn[i].value_or("") << "' vs '" << nn[i].value_or("") << "'" << std::endl; throw std::runtime_error("from_arrays brace-init: names divergence"); } } for (size_t i = 0; i < via_brace.size(); ++i) { std::vector tup_brace = via_brace.get_tuple_str(i); std::vector tup_named = via_named.get_tuple_str(i); if (tup_brace != tup_named) { std::cout << " [FAIL] row " << i << " differs" << std::endl; throw std::runtime_error("from_arrays brace-init: content divergence"); } } } // Case C: integer element type - exercises template deduction beyond string { .. _example-multiindex-take-27: .. dropdown:: take (pd_test_1_all.cpp:5903) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5893 :emphasize-lines: 11 // Inherited Operations Tests // ============================================================================ void pd_test_categorical_index_take() { std::cout << "========= inherited take =============================="; pandas::CategoricalArray arr({"a", "b", "c", "d"}); pandas::CategoricalIndex idx(arr); std::vector indices = {0, 2, 3}; pandas::ExtensionIndex taken = idx.take(indices); bool passed = (taken.size() == 3); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_take()" << std::endl; throw std::runtime_error("pd_test_categorical_index_take failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-where-28: .. dropdown:: where (pd_test_1_all.cpp:22018) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 22008 :emphasize-lines: 11 data["B"] = {5.0, 6.0, 7.0, 8.0}; pandas::DataFrame df(data); // Create condition DataFrame (values > 2) std::map> cond_data; cond_data["A"] = {false, false, true, true}; // 1<=2, 2<=2, 3>2, 4>2 cond_data["B"] = {true, true, true, true}; // all >2 pandas::DataFrame cond(cond_data); // Apply where with replacement value -1 pandas::DataFrame result = df.where(cond, -1.0); // Get column index for A - it's sorted alphabetically in std::map size_t col_a_idx = df.get_column_index("A"); size_t col_b_idx = df.get_column_index("B"); bool passed = true; std::string error_msg; // Check A column values std::string a0 = result.iat(0, col_a_idx) == -1.0 ? "ok" : "fail"; .. _example-multiindex-drop-29: .. dropdown:: drop (pd_test_1_all.cpp:6558) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6548 :emphasize-lines: 11 if (df.ncols() != 2) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : pop ncols != 2" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: pop ncols != 2"); } if (!popped) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : popped is null" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: popped is null"); } // Test drop columns auto dropped = df.drop(std::vector{"B"}, 1); if (dropped.ncols() != 1) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : drop ncols != 1" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: drop ncols != 1"); } // Test rename auto renamed = df.rename_columns(std::map{{"A", "X"}}); if (!renamed.has_column("X")) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : rename failed" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: rename failed"); .. _example-multiindex-drop_duplicates-30: .. dropdown:: drop_duplicates (pd_test_1_all.cpp:6639) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6629 :emphasize-lines: 11 } } // Test drop_duplicates { std::map> dup_data; dup_data["A"] = {1, 1, 2, 2}; dup_data["B"] = {1, 1, 2, 3}; pandas::DataFrame df_dup(dup_data); auto deduped = df_dup.drop_duplicates(); // Rows 0 and 1 are duplicates (A=1, B=1), so should have 3 rows if (deduped.nrows() != 3) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : drop_duplicates nrows != 3, got " << deduped.nrows() << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: drop_duplicates"); } } // Test assign { std::map> assign_data; .. _example-multiindex-droplevel-31: .. dropdown:: droplevel (pd_test_1_all.cpp:14428) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14418 :emphasize-lines: 11 void pd_test_multiindex_droplevel() { std::cout << "========= droplevel =================================== "; std::vector> arrays = { {"a", "a", "b"}, {"x", "y", "z"}, {"1", "2", "3"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); pandas::MultiIndex dropped = mi.droplevel(1); bool passed = true; if (dropped.nlevels() != 2) { std::cout << " [FAIL] : nlevels should be 2 after drop" << std::endl; passed = false; } // Check remaining levels auto tup = dropped[0]; .. _example-multiindex-dropna-32: .. dropdown:: dropna (pd_test_1_all.cpp:531) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 521 :emphasize-lines: 11 } // Test isna array numpy::NDArray na_mask = arr.isna(); if (na_mask.getSize() != 4) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : isna size != 4" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: isna size != 4"); } // Test dropna pandas::CategoricalArray dropped = arr.dropna(); if (dropped.size() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : dropna size != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: dropna size != 2"); } // Test fillna (fill with existing category) pandas::CategoricalArray filled = arr.fillna("a"); // 'a' is in categories if (filled.has_na()) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : fillna should have no NA" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: fillna should have no NA"); .. _example-multiindex-insert-33: .. dropdown:: insert (pd_test_1_all.cpp:12028) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 12018 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } void pd_test_index_insert_delete() { std::cout << "========= insert and delete ==========================="; pandas::Index idx{1, 2, 4, 5}; auto inserted = idx.insert(2, 3); bool passed = (inserted.size() == 5); passed = passed && (inserted[2] == 3); auto deleted = inserted.delete_(2); passed = passed && (deleted.size() == 4); passed = passed && deleted.equals(idx); if (!passed) { std::cout << " [FAIL] : in pd_test_index_insert_delete() : insert/delete failed" << std::endl; throw std::runtime_error("pd_test_index_insert_delete failed"); .. _example-multiindex-reindex-34: .. dropdown:: reindex (pd_test_1_all.cpp:6708) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6698 :emphasize-lines: 11 } } // Test reindex rows { std::map> data; data["A"] = {1.0, 2.0, 3.0}; pandas::DataFrame df(data); df = df.set_axis({"x", "y", "z"}, 0); auto reindexed = df.reindex({"x", "z", "w"}, 0); if (reindexed.nrows() != 3) { std::cout << " [FAIL] : in pd_test_dataframe_index_ops() : reindex wrong nrows" << std::endl; throw std::runtime_error("pd_test_dataframe_index_ops failed: reindex nrows"); } // 'w' should have NaN std::string val = reindexed["A"].get_value_str(2); if (!std::isnan(std::stod(val))) { std::cout << " [FAIL] : in pd_test_dataframe_index_ops() : missing label should be NaN" << std::endl; throw std::runtime_error("pd_test_dataframe_index_ops failed: reindex NaN"); } .. _example-multiindex-rename-35: .. dropdown:: rename (pd_test_1_all.cpp:5816) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5806 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_index_rename() { std::cout << "========= rename ======================================"; pandas::CategoricalArray arr({"x", "y"}); pandas::CategoricalIndex idx(arr, "old_name"); pandas::CategoricalIndex renamed = idx.rename("new_name"); bool passed = (renamed.name().has_value() && *renamed.name() == "new_name" && renamed.size() == idx.size() && renamed.categories() == idx.categories()); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_rename()" << std::endl; throw std::runtime_error("pd_test_categorical_index_rename failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-reorder_levels-36: .. dropdown:: reorder_levels (pd_test_1_all.cpp:14495) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14485 :emphasize-lines: 11 void pd_test_multiindex_reorder_levels() { std::cout << "========= reorder_levels ============================== "; std::vector> arrays = { {"a", "b"}, {"x", "y"}, {"1", "2"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); pandas::MultiIndex reordered = mi.reorder_levels({2, 0, 1}); bool passed = true; auto tup = reordered[0]; if (tup[0] != "1" || tup[1] != "a" || tup[2] != "x") { std::cout << " [FAIL] : reordered tuple should be ('1', 'a', 'x')" << std::endl; passed = false; } if (!passed) { .. _example-multiindex-set_names-37: .. dropdown:: set_names (pd_test_1_all.cpp:14519) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14509 :emphasize-lines: 11 std::cout << "-> tests passed" << std::endl; } void pd_test_multiindex_set_names() { std::cout << "========= set_names =================================== "; std::vector> arrays = {{"a", "b"}, {"x", "y"}}; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); std::vector> new_names = {"level_a", "level_b"}; pandas::MultiIndex named = mi.set_names(new_names); bool passed = (named.names()[0] == "level_a" && named.names()[1] == "level_b"); if (!passed) { std::cout << " [FAIL] : names not set correctly" << std::endl; throw std::runtime_error("pd_test_multiindex_set_names failed"); } std::cout << "-> tests passed" << std::endl; } .. _example-multiindex-swaplevel-38: .. dropdown:: swaplevel (pd_test_1_all.cpp:14461) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14451 :emphasize-lines: 11 void pd_test_multiindex_swaplevel() { std::cout << "========= swaplevel =================================== "; std::vector> arrays = { {"a", "b"}, {"x", "y"} }; std::vector> names = {"first", "second"}; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays, names); pandas::MultiIndex swapped = mi.swaplevel(0, 1); bool passed = true; // Tuple should be reversed auto tup = swapped[0]; if (tup[0] != "x" || tup[1] != "a") { std::cout << " [FAIL] : swapped tuple should be ('x', 'a')" << std::endl; passed = false; } .. _example-multiindex-fillna-39: .. dropdown:: fillna (pd_test_1_all.cpp:537) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 527 :emphasize-lines: 11 throw std::runtime_error("pd_test_categorical_array_na_handling failed: isna size != 4"); } // Test dropna pandas::CategoricalArray dropped = arr.dropna(); if (dropped.size() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : dropna size != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: dropna size != 2"); } // Test fillna (fill with existing category) pandas::CategoricalArray filled = arr.fillna("a"); // 'a' is in categories if (filled.has_na()) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : fillna should have no NA" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: fillna should have no NA"); } std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_array_add_categories() { .. _example-multiindex-isna-40: .. dropdown:: isna (pd_test_1_all.cpp:524) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 514 :emphasize-lines: 11 throw std::runtime_error("pd_test_categorical_array_na_handling failed: has_na() should be true"); } // Test count (non-NA) if (arr.count() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : count() != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: count() != 2"); } // Test isna array numpy::NDArray na_mask = arr.isna(); if (na_mask.getSize() != 4) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : isna size != 4" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: isna size != 4"); } // Test dropna pandas::CategoricalArray dropped = arr.dropna(); if (dropped.size() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : dropna size != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_na_handling failed: dropna size != 2"); .. _example-multiindex-isnull-41: .. dropdown:: isnull (pd_test_3_all.cpp:671) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 661 :emphasize-lines: 11 // Category 5: Index Null Detection // ============================================================================ void pd_test_3_all_index_null_detection() { std::cout << "========= Index.isnull/notnull() ====================="; // Test with float index (can have NaN) std::vector vals = {1.0, std::nan(""), 3.0, std::nan("")}; pandas::Index idx(vals); numpy::NDArray isnull_result = idx.isnull(); if (isnull_result.getSize() != 4) { std::cout << " [FAIL] : in pd_test_3_all_index_null_detection() : isnull() size mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_index_null_detection failed: isnull() size"); } // Index 0: 1.0 -> not null if (isnull_result.getElementAt({0})) { std::cout << " [FAIL] : in pd_test_3_all_index_null_detection() : index 0 should not be null" << std::endl; throw std::runtime_error("pd_test_3_all_index_null_detection failed: index 0"); } // Index 1: NaN -> null .. _example-multiindex-notna-42: .. dropdown:: notna (pd_test_1_all.cpp:6595) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6585 :emphasize-lines: 11 if (!na_mask.getElementAt({2, 1})) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : isna at (2,1) should be true" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: isna at (2,1)"); } // Row 0, col 0 should NOT be NA if (na_mask.getElementAt({0, 0})) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : isna at (0,0) should be false" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: isna at (0,0)"); } auto notna_mask = df_na.notna(); if (notna_mask.getElementAt({1, 0})) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : notna at (1,0) should be false" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: notna at (1,0)"); } } // Test fillna { std::map> float_data; float_data["X"] = {1.0, std::nan(""), 3.0}; .. _example-multiindex-notnull-43: .. dropdown:: notnull (pd_test_3_all.cpp:665) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 655 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Category 5: Index Null Detection // ============================================================================ void pd_test_3_all_index_null_detection() { std::cout << "========= Index.isnull/notnull() ====================="; // Test with float index (can have NaN) std::vector vals = {1.0, std::nan(""), 3.0, std::nan("")}; pandas::Index idx(vals); numpy::NDArray isnull_result = idx.isnull(); if (isnull_result.getSize() != 4) { std::cout << " [FAIL] : in pd_test_3_all_index_null_detection() : isnull() size mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_index_null_detection failed: isnull() size"); } .. _example-multiindex-max-44: .. dropdown:: max (pd_test_1_all.cpp:771) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 761 :emphasize-lines: 11 pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats, true); // ordered // Test min std::optional min_val = arr.min(); if (!min_val.has_value() || *min_val != "low") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : min != 'low'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: min != 'low'"); } // Test max std::optional max_val = arr.max(); if (!max_val.has_value() || *max_val != "high") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : max != 'high'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: max != 'high'"); } // Test unordered throws for min/max pandas::CategoricalArray unordered = arr.as_unordered(); bool threw = false; try { unordered.min(); .. _example-multiindex-min-45: .. dropdown:: min (pd_test_1_all.cpp:764) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 754 :emphasize-lines: 11 } void pd_test_categorical_array_ordered_operations() { std::cout << "========= CategoricalArray: ordered operations (min/max) ======================= "; std::vector cats = {"low", "medium", "high"}; std::vector codes = {0, 2, 1, 0, -1}; // low, high, medium, low, NA pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats, true); // ordered // Test min std::optional min_val = arr.min(); if (!min_val.has_value() || *min_val != "low") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : min != 'low'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: min != 'low'"); } // Test max std::optional max_val = arr.max(); if (!max_val.has_value() || *max_val != "high") { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : max != 'high'" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: max != 'high'"); .. _example-multiindex-nunique-46: .. dropdown:: nunique (pd_test_1_all.cpp:10604) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10594 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_nunique() { std::cout << "========= nunique ========================="; pandas::CategoricalArray arr({"a", "b", "a", "c", "b", std::nullopt}); pandas::CategoricalIndex idx(arr); bool passed = (idx.nunique(true) == 3 && idx.nunique(false) == 4); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_nunique() : nunique check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_nunique failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_factorize() { std::cout << "========= factorize ========================="; .. _example-multiindex-groupby-47: .. dropdown:: groupby (pd_test_1_all.cpp:11495) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 11485 :emphasize-lines: 11 std::cout << "========= GroupBy basic ========================="; // Create DataFrame with category column std::map> data = { {"category", {1.0, 1.0, 2.0, 2.0, 2.0}}, {"value", {10.0, 20.0, 30.0, 40.0, 50.0}} }; pandas::DataFrame df(data); // Test groupby auto grouped = df.groupby("category"); bool passed = grouped.ngroups() == 2; if (!passed) { std::cout << " [FAIL] : in pd_test_groupby_basic() : ngroups should be 2" << std::endl; throw std::runtime_error("pd_test_groupby_basic failed: ngroups should be 2"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-map-48: .. dropdown:: map (pd_test_1_all.cpp:5839) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5829 :emphasize-lines: 11 // Map Tests // ============================================================================ void pd_test_categorical_index_map() { std::cout << "========= map ========================================="; pandas::CategoricalArray arr({"yes", "no", "yes"}); pandas::CategoricalIndex idx(arr); std::unordered_map mapping = {{"yes", "1"}, {"no", "0"}}; pandas::CategoricalIndex mapped = idx.map(mapping); bool passed = (mapped.has_category("1") && mapped.has_category("0") && !mapped.has_category("yes") && !mapped.has_category("no")); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_map()" << std::endl; throw std::runtime_error("pd_test_categorical_index_map failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-equal_levels-49: .. dropdown:: equal_levels (pd_test_3_all.cpp:8979) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 8969 :emphasize-lines: 11 } std::cout << " -> tests passed (placeholder)" << std::endl; } // ============================================================================ // Category 34: Plan 07 - MultiIndex New Tests (equal_levels, from_frame, etc.) // ============================================================================ void pd_test_3_all_multiindex_equal_levels() { std::cout << "========= MultiIndex.equal_levels() ==============="; // Create two MultiIndex with same levels std::vector> arrays1 = {{"a", "a", "b", "b"}, {"1", "2", "1", "2"}}; pandas::MultiIndex mi1 = pandas::MultiIndex::from_arrays(arrays1); std::vector> arrays2 = {{"a", "a", "b", "b"}, {"1", "2", "1", "2"}}; pandas::MultiIndex mi2 = pandas::MultiIndex::from_arrays(arrays2); // Test equal levels bool eq = mi1.equal_levels(mi2); .. _example-multiindex-equals-50: .. dropdown:: equals (pd_test_1_all.cpp:5866) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5856 :emphasize-lines: 11 std::cout << "========= equals ======================================"; pandas::CategoricalArray arr1({"a", "b", "a"}); pandas::CategoricalArray arr2({"a", "b", "a"}); pandas::CategoricalArray arr3({"a", "b", "c"}); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalIndex idx2(arr2); pandas::CategoricalIndex idx3(arr3); bool passed = (idx1.equals(idx2) && !idx1.equals(idx3)); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_equals()" << std::endl; throw std::runtime_error("pd_test_categorical_index_equals failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_index_identical() { std::cout << "========= identical ==================================="; .. _example-multiindex-levels-51: .. dropdown:: levels (pd_test_2_all.cpp:9787) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9777 :emphasize-lines: 11 pandas::DataFrame df(data); std::vector hier_index = { "Final exam:History:January", "Final exam:Geography:February", "Coursework:History:March", "Coursework:Geography:April" }; df.set_index(std::make_unique>(hier_index)); // Default: swap last two levels (i=-2, j=-1) pandas::DataFrame result = df.swaplevel(); std::string idx0 = result.index().get_value_str(0); std::string idx1 = result.index().get_value_str(1); std::string idx2 = result.index().get_value_str(2); std::string idx3 = result.index().get_value_str(3); bool passed = (idx0 == "Final exam:January:History" && idx1 == "Final exam:February:Geography" && idx2 == "Coursework:March:History" && .. _example-multiindex-levshape-52: .. dropdown:: levshape (pd_test_1_all.cpp:14312) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14302 :emphasize-lines: 11 void pd_test_multiindex_levshape() { std::cout << "========= levshape property =========================== "; std::vector> arrays = { {"a", "a", "b", "b", "c"}, {"x", "y", "x", "y", "z"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); auto shape = mi.levshape(); bool passed = (shape.size() == 2 && shape[0] == 3 && shape[1] == 3); if (!passed) { std::cout << " [FAIL] : levshape should be [3, 3]" << std::endl; throw std::runtime_error("pd_test_multiindex_levshape failed"); } std::cout << "-> tests passed" << std::endl; } .. _example-multiindex-argsort-53: .. dropdown:: argsort (pd_test_1_all.cpp:1304) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1294 :emphasize-lines: 11 std::cout << "========= DatetimeArray: sorting ======================= "; pandas::DatetimeArray arr(std::vector{ "2023-06-15", "NaT", "2023-01-01", "2023-12-31" }); // argsort ascending auto indices = arr.argsort(true, "last"); // Expected order: 2023-01-01(2), 2023-06-15(0), 2023-12-31(3), NaT(1) if (indices.getElementAt({0}) != 2) { std::cout << " [FAIL] : argsort: first should be index 2 (2023-01-01)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argsort first"); } if (indices.getElementAt({3}) != 1) { std::cout << " [FAIL] : argsort: last should be index 1 (NaT)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: NaT position"); } .. _example-multiindex-searchsorted-54: .. dropdown:: searchsorted (pd_test_1_all.cpp:18958) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18948 :emphasize-lines: 11 // ========================================================================= // Search Tests // ========================================================================= void pd_test_range_index_searchsorted() { std::cout << "========= searchsorted ================================ "; pandas::RangeIndex ri(0, 10, 2); // [0, 2, 4, 6, 8] bool passed = (ri.searchsorted(4, "left") == 2 && ri.searchsorted(4, "right") == 3 && ri.searchsorted(3, "left") == 2 && // 3 would go between 2 and 4 ri.searchsorted(-1, "left") == 0 && // Before all ri.searchsorted(10, "left") == 5); // After all if (!passed) { std::cout << " [FAIL] : searchsorted" << std::endl; throw std::runtime_error("pd_test_range_index_searchsorted failed"); } .. _example-multiindex-sort_values-55: .. dropdown:: sort_values (pd_test_1_all.cpp:6408) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6398 :emphasize-lines: 11 void pd_test_dataframe_sorting() { std::cout << "========= sorting =========================="; std::map> data; data["A"] = {3.0, 1.0, 4.0, 1.0, 5.0}; data["B"] = {9.0, 2.0, 6.0, 5.0, 3.0}; pandas::DataFrame df(data); // Test sort_values ascending auto sorted_asc = df.sort_values("A", true); // First value should be smallest (1.0) std::string first_val = sorted_asc["A"].get_value_str(0); if (std::stod(first_val) != 1.0) { std::cout << " [FAIL] : in pd_test_dataframe_sorting() : sort_values asc first != 1" << std::endl; throw std::runtime_error("pd_test_dataframe_sorting failed: sort_values asc first != 1"); } // Test sort_values descending auto sorted_desc = df.sort_values("A", false); first_val = sorted_desc["A"].get_value_str(0); .. _example-multiindex-to_frame-56: .. dropdown:: to_frame (pd_test_3_all.cpp:4931) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4921 :emphasize-lines: 11 size_t usage = mi.memory_usage(true); if (usage == 0) { throw std::runtime_error("memory_usage() should return > 0"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_multiindex_to_frame() { std::cout << "========= MultiIndex.to_frame() ======================="; std::vector> arrays = {{"a", "b"}, {"x", "y"}}; std::vector> names = {"first", "second"}; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays, names); auto frame = mi.to_frame(); if (frame.find("first") == frame.end() || frame.find("second") == frame.end()) { throw std::runtime_error("to_frame() missing columns"); } .. _example-multiindex-transpose-57: .. dropdown:: transpose (pd_test_1_all.cpp:16648) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 16638 :emphasize-lines: 11 std::cout << " [FAIL] : in pd_test_ndframe_transpose() : T_() size" << std::endl; throw std::runtime_error("pd_test_ndframe_transpose failed: T_() size"); } passed = transposed[0] == 1 && transposed[1] == 2 && transposed[2] == 3; if (!passed) { std::cout << " [FAIL] : in pd_test_ndframe_transpose() : T_() values" << std::endl; throw std::runtime_error("pd_test_ndframe_transpose failed: T_() values"); } // Test transpose() alias auto transposed2 = s.transpose(); passed = transposed2.size() == s.size(); if (!passed) { std::cout << " [FAIL] : in pd_test_ndframe_transpose() : transpose() size" << std::endl; throw std::runtime_error("pd_test_ndframe_transpose failed: transpose() size"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-append-58: .. dropdown:: append (pd_test_1_all.cpp:10650) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10640 :emphasize-lines: 11 std::cout << "========= append ========================="; // Use same categories for both arrays (required by CategoricalArray::concat) std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"c", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto appended = idx1.append(idx2); bool passed = (appended.size() == 4); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_append() : append check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_append failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-join-59: .. dropdown:: join (pd_test_1_all.cpp:12353) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 12343 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_index_join() { std::cout << "========= join ========================================"; pandas::Index idx1{1, 2, 3}; pandas::Index idx2{2, 3, 4}; auto [inner_joined, left_idx, right_idx] = idx1.join(idx2, "inner"); bool passed = (inner_joined.size() == 2); // {2, 3} auto [outer_joined, ol_idx, or_idx] = idx1.join(idx2, "outer"); passed = passed && (outer_joined.size() == 4); // {1, 2, 3, 4} if (!passed) { std::cout << " [FAIL] : in pd_test_index_join() : join failed" << std::endl; throw std::runtime_error("pd_test_index_join failed"); } .. _example-multiindex-asof-60: .. dropdown:: asof (pd_test_2_all.cpp:366) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 356 :emphasize-lines: 11 std::cout << "====================================== [OK] pd_test_add_prefix test suite ========================== " << std::endl; return 0; } } // namespace dataframe_tests // ------------------- pd_test_add_prefix.cpp (end) ----------------------------- // ------------------- pd_test_asof.cpp (start) ----------------------------- // dataframe_tests/pd_test_asof.cpp // Test for DataFrame.asof() method #include #include #include #include #include "../pandas/pd_dataframe.h" // CRITICAL: No using namespace directives namespace dataframe_tests { .. _example-multiindex-asof_locs-61: .. dropdown:: asof_locs (pd_test_3_all.cpp:3557) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3547 :emphasize-lines: 11 throw std::runtime_error("all() should be true for empty index"); } if (empty_idx.any()) { throw std::runtime_error("any() should be false for empty index"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_index_asof() { std::cout << "========= Index.asof()/asof_locs() ================="; // Test with monotonically increasing index pandas::Index idx({10, 20, 30, 40, 50}); // Exact match auto result = idx.asof(30); if (!result.has_value() || result.value() != 30) { throw std::runtime_error("asof() exact match should return 30"); } .. _example-multiindex-diff-62: .. dropdown:: diff (pd_test_1_all.cpp:5171) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5161 :emphasize-lines: 11 } void pd_test_arithmetic_dataframe_diff_shift() { std::cout << "========= DataFrame diff/shift =================="; std::map> data; data["A"] = {1.0, 3.0, 6.0, 10.0}; pandas::DataFrame df(data); // diff: [NaN, 2, 3, 4] auto d = df.diff(); std::string val = d["A"].get_value_str(1); bool passed = std::abs(std::stod(val) - 2.0) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_dataframe_diff_shift() : diff failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_dataframe_diff_shift failed: diff failed"); } // First element should be NaN val = d["A"].get_value_str(0); passed = std::isnan(std::stod(val)); .. _example-multiindex-difference-63: .. dropdown:: difference (pd_test_1_all.cpp:10718) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10708 :emphasize-lines: 11 std::cout << "========= difference ========================="; // Use same categories for both arrays std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b", "c", "d"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"b", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto diff = idx1.difference(idx2); bool passed = (diff.size() == 2 && diff.contains("a") && diff.contains("c") && !diff.contains("b") && !diff.contains("d")); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_difference() : difference check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_difference failed"); } std::cout << " -> tests passed" << std::endl; .. _example-multiindex-shift-64: .. dropdown:: shift (pd_test_1_all.cpp:5188) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5178 :emphasize-lines: 11 // First element should be NaN val = d["A"].get_value_str(0); passed = std::isnan(std::stod(val)); if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_dataframe_diff_shift() : diff NaN failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_dataframe_diff_shift failed: diff NaN failed"); } // shift: [NaN, 1, 3, 6] auto s = df.shift(); val = s["A"].get_value_str(1); passed = std::abs(std::stod(val) - 1.0) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_dataframe_diff_shift() : shift failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_dataframe_diff_shift failed: shift failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-to_flat_index-65: .. dropdown:: to_flat_index (pd_test_1_all.cpp:14733) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14723 :emphasize-lines: 11 void pd_test_multiindex_to_flat_index() { std::cout << "========= to_flat_index =============================== "; std::vector> arrays = { {"a", "b"}, {"x", "y"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); auto flat = mi.to_flat_index(); bool passed = (flat.size() == 2 && flat[0][0] == "a" && flat[0][1] == "x" && flat[1][0] == "b" && flat[1][1] == "y"); if (!passed) { std::cout << " [FAIL] : to_flat_index incorrect" << std::endl; throw std::runtime_error("pd_test_multiindex_to_flat_index failed"); } .. _example-multiindex-to_list-66: .. dropdown:: to_list (pd_test_1_all.cpp:10247) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10237 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_to_list() { std::cout << "========= to_list ========================="; pandas::CategoricalArray arr({"x", "y", "z"}); pandas::CategoricalIndex idx(arr); auto list = idx.to_list(); bool passed = (list.size() == 3 && list[0].has_value() && *list[0] == "x" && list[1].has_value() && *list[1] == "y" && list[2].has_value() && *list[2] == "z"); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_to_list() : to_list check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_to_list failed"); } .. _example-multiindex-to_numpy-67: .. dropdown:: to_numpy (pd_test_1_all.cpp:16764) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 16754 :emphasize-lines: 11 // ===================================================================== // to_numpy Tests // ===================================================================== void pd_test_ndframe_to_numpy() { std::cout << "========= to_numpy =============================================" << std::endl; pandas::Series s({10, 20, 30}); auto arr = s.to_numpy(); bool passed = arr.getSize() == 3; if (!passed) { std::cout << " [FAIL] : in pd_test_ndframe_to_numpy() : size" << std::endl; throw std::runtime_error("pd_test_ndframe_to_numpy failed: size"); } passed = arr.getElementAt({0}) == 10 && arr.getElementAt({1}) == 20 && arr.getElementAt({2}) == 30; if (!passed) { std::cout << " [FAIL] : in pd_test_ndframe_to_numpy() : values" << std::endl; .. _example-multiindex-to_string-68: .. dropdown:: to_string (pd_test_1_all.cpp:2693) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2683 :emphasize-lines: 11 pandas::PeriodArray arr_m(std::vector{ "2020-01", "NaT", "2025-06" }, "M"); // Year auto years = arr_m.year(); auto y0 = years[0]; if (!y0.has_value() || y0.value() != 2020) { std::cout << " [FAIL] : year[0] should be 2020, got " << (y0.has_value() ? std::to_string(y0.value()) : "NA") << std::endl; throw std::runtime_error("pd_test_period_array_year_month_quarter failed: year[0]"); } auto y1 = years[1]; if (y1.has_value()) { std::cout << " [FAIL] : year[1] should be NA (NaT)" << std::endl; throw std::runtime_error("pd_test_period_array_year_month_quarter failed: year[1] should be NA"); } auto y2 = years[2]; .. _example-multiindex-tolist-69: .. dropdown:: tolist (pd_test_3_all.cpp:2300) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2290 :emphasize-lines: 11 threw = true; } if (!threw) { throw std::runtime_error("swapaxes should throw for invalid axes"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_categorical_to_list() { std::cout << "========= CategoricalArray.to_list()/tolist() ========="; std::vector> values = {"a", "b", std::nullopt, "c"}; pandas::CategoricalArray arr(values); auto list = arr.to_list(); if (list.size() != 4 || *list[0] != "a" || *list[1] != "b" || list[2].has_value() || *list[3] != "c") { throw std::runtime_error("to_list failed"); } .. _example-multiindex-astype-70: .. dropdown:: astype (pd_test_1_all.cpp:21292) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 21282 :emphasize-lines: 11 std::cout << "========= astype all columns to float64 ============="; // Create DataFrame with int64 columns std::map> data; data["A"] = {1, 2, 3, 4, 5}; data["B"] = {10, 20, 30, 40, 50}; pandas::DataFrame df(data); // Convert all columns to float64 pandas::DataFrame df_float = df.astype("float64"); // Verify dtype changed pandas::Series dtypes = df_float.dtypes(); bool passed = true; if (dtypes[static_cast(0)] != "float64") { std::cout << " [FAIL] : in pd_test_astype_all_columns_to_float64() : column A dtype is " << dtypes[static_cast(0)] << ", expected float64" << std::endl; passed = false; } if (dtypes[static_cast(1)] != "float64") { .. _example-multiindex-copy-71: .. dropdown:: copy (pd_test_1_all.cpp:5798) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5788 :emphasize-lines: 11 // ============================================================================ // Copy/Rename Tests // ============================================================================ void pd_test_categorical_index_copy() { std::cout << "========= copy ========================================"; pandas::CategoricalArray arr({"a", "b", "c"}); pandas::CategoricalIndex idx(arr, "original"); pandas::CategoricalIndex copied = idx.copy(); bool passed = (copied.size() == idx.size() && copied.name() == idx.name() && copied.categories() == idx.categories() && copied.ordered() == idx.ordered()); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_copy()" << std::endl; throw std::runtime_error("pd_test_categorical_index_copy failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-infer_objects-72: .. dropdown:: infer_objects (pd_test_1_all.cpp:27595) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27585 :emphasize-lines: 11 // Create DataFrame with string column containing integers std::map> data; data["A"] = {"1", "2", "3", "4", "5"}; pandas::DataFrame df(data); // Before inference, dtype should be string/object std::string before_dtype = df["A"].dtype_name(); // Apply infer_objects pandas::DataFrame result = df.infer_objects(); // After inference, dtype should be int64 std::string after_dtype = result["A"].dtype_name(); bool passed = (after_dtype == "int64"); if (!passed) { std::cout << " [FAIL] : in pd_test_infer_objects_integer_column() : expected int64, got " << after_dtype << std::endl; throw std::runtime_error("pd_test_infer_objects_integer_column failed"); } .. _example-multiindex-view-73: .. dropdown:: view (pd_test_3_all.cpp:2147) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2137 :emphasize-lines: 11 throw std::runtime_error("memory_usage shallow too small"); } if (deep < shallow) { throw std::runtime_error("memory_usage deep should be >= shallow"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_categorical_ravel_view() { std::cout << "========= CategoricalArray.ravel()/view() ============="; std::vector> values = {"a", "b", "c"}; pandas::CategoricalArray arr(values); auto raveled = arr.ravel(); if (raveled.size() != 3 || !raveled.equals(arr)) { throw std::runtime_error("ravel failed"); } auto viewed = arr.view(); .. _example-multiindex-duplicated-74: .. dropdown:: duplicated (pd_test_1_all.cpp:10583) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10573 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_duplicated() { std::cout << "========= duplicated ========================="; pandas::CategoricalArray arr({"a", "b", "a", "c", "a"}); pandas::CategoricalIndex idx(arr); auto dup_mask = idx.duplicated("first"); bool passed = (dup_mask.getElementAt({0}) == false && dup_mask.getElementAt({1}) == false && dup_mask.getElementAt({2}) == true && dup_mask.getElementAt({3}) == false && dup_mask.getElementAt({4}) == true); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_duplicated() : duplicated check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_duplicated failed"); } .. _example-multiindex-intersection-75: .. dropdown:: intersection (pd_test_1_all.cpp:10672) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10662 :emphasize-lines: 11 std::cout << "========= intersection ========================="; // Use same categories for both arrays std::vector cats = {"a", "b", "c", "d", "e", "f"}; pandas::CategoricalArray arr1({"a", "b", "c", "d"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"b", "c", "e", "f"}, cats); pandas::CategoricalIndex idx2(arr2); auto inter = idx1.intersection(idx2); bool passed = (inter.size() == 2 && inter.contains("b") && inter.contains("c")); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_intersection() : intersection check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_intersection failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-isin-76: .. dropdown:: isin (pd_test_1_all.cpp:5938) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5928 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_index_isin() { std::cout << "========= inherited isin =============================="; pandas::CategoricalArray arr({"a", "b", "c", "d"}); pandas::CategoricalIndex idx(arr); std::vector values = {"a", "c"}; numpy::NDArray mask = idx.isin(values); bool passed = (mask.getSize() == 4 && mask.getElementAt({0}) == true && // a mask.getElementAt({1}) == false && // b mask.getElementAt({2}) == true && // c mask.getElementAt({3}) == false); // d if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_isin()" << std::endl; throw std::runtime_error("pd_test_categorical_index_isin failed"); } .. _example-multiindex-symmetric_difference-77: .. dropdown:: symmetric_difference (pd_test_1_all.cpp:10742) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10732 :emphasize-lines: 11 std::cout << "========= symmetric_difference ========================="; // Use same categories for both arrays std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b", "c"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"b", "c", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto sym_diff = idx1.symmetric_difference(idx2); bool passed = (sym_diff.size() == 2 && sym_diff.contains("a") && sym_diff.contains("d") && !sym_diff.contains("b") && !sym_diff.contains("c")); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_symmetric_difference() : symmetric_difference check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_symmetric_difference failed"); } std::cout << " -> tests passed" << std::endl; .. _example-multiindex-union_-78: .. dropdown:: union_ (pd_test_1_all.cpp:10694) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10684 :emphasize-lines: 11 std::cout << "========= union ========================="; // Use same categories for both arrays std::vector cats = {"a", "b", "c", "d", "e"}; pandas::CategoricalArray arr1({"a", "b", "c"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"b", "c", "d", "e"}, cats); pandas::CategoricalIndex idx2(arr2); auto uni = idx1.union_(idx2); bool passed = (uni.size() == 5 && uni.contains("a") && uni.contains("b") && uni.contains("c") && uni.contains("d") && uni.contains("e")); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_union() : union check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_union failed"); } std::cout << " -> tests passed" << std::endl; .. _example-multiindex-unique-79: .. dropdown:: unique (pd_test_1_all.cpp:1345) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1335 :emphasize-lines: 11 pandas::DatetimeArray arr(std::vector{ "2023-01-01", "2023-06-15", "2023-01-01", "NaT", "2023-06-15", "NaT" }); // unique auto uniq = arr.unique(); // Should have: NaT, 2023-01-01, 2023-06-15 (3 unique values) if (uniq.size() != 3) { std::cout << " [FAIL] : unique size should be 3, got " << uniq.size() << std::endl; throw std::runtime_error("pd_test_datetime_array_unique failed: size"); } // factorize auto [codes, uniques] = arr.factorize(); // Codes for NaT should be -1 if (codes.getElementAt({3}) != -1) { .. _example-multiindex-is_-80: .. dropdown:: is_ (pd_test_3_all.cpp:3972) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3962 :emphasize-lines: 11 // For typed Index, this is a no-op if (result.size() != 5) { throw std::runtime_error("infer_objects size should be 5"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_index_is_() { std::cout << "========= Index.is_() =============================="; pandas::Index idx1({1, 2, 3, 4, 5}); pandas::Index idx2({1, 2, 3, 4, 5}); // Different object // Different objects should not be the same if (idx1.is_(idx2)) { throw std::runtime_error("different objects should not be is_() equal"); } // Same object should be the same .. _example-multiindex-is_boolean-81: .. dropdown:: is_boolean (pd_test_3_all.cpp:3290) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3280 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_datetime_index_type_checks() { std::cout << "========= DatetimeIndex type checks ======================"; pandas::DatetimeIndex idx = pandas::date_range("2024-01-01", "2024-01-05", std::nullopt, "D"); // Type check methods if (idx.is_boolean()) { throw std::runtime_error("is_boolean() should be false"); } if (idx.is_categorical()) { throw std::runtime_error("is_categorical() should be false"); } if (idx.is_floating()) { throw std::runtime_error("is_floating() should be false"); } if (idx.is_integer()) { throw std::runtime_error("is_integer() should be false"); .. _example-multiindex-is_categorical-82: .. dropdown:: is_categorical (pd_test_3_all.cpp:3293) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3283 :emphasize-lines: 11 void pd_test_3_all_datetime_index_type_checks() { std::cout << "========= DatetimeIndex type checks ======================"; pandas::DatetimeIndex idx = pandas::date_range("2024-01-01", "2024-01-05", std::nullopt, "D"); // Type check methods if (idx.is_boolean()) { throw std::runtime_error("is_boolean() should be false"); } if (idx.is_categorical()) { throw std::runtime_error("is_categorical() should be false"); } if (idx.is_floating()) { throw std::runtime_error("is_floating() should be false"); } if (idx.is_integer()) { throw std::runtime_error("is_integer() should be false"); } if (idx.is_interval()) { throw std::runtime_error("is_interval() should be false"); .. _example-multiindex-is_floating-83: .. dropdown:: is_floating (pd_test_3_all.cpp:622) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 612 :emphasize-lines: 11 // Test with integer index pandas::IndexDtype int_dtype; if (!int_dtype.is_numeric()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be numeric" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_numeric"); } if (!int_dtype.is_integer()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be integer" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_integer"); } if (int_dtype.is_floating()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be floating" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_floating"); } if (int_dtype.is_object()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be object" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_object"); } // Test with float index pandas::IndexDtype float_dtype; .. _example-multiindex-is_integer-84: .. dropdown:: is_integer (pd_test_3_all.cpp:618) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 608 :emphasize-lines: 11 void pd_test_3_all_index_dtype_checks() { std::cout << "========= IndexDtype.is_numeric/integer/floating/object() "; // Test with integer index pandas::IndexDtype int_dtype; if (!int_dtype.is_numeric()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be numeric" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_numeric"); } if (!int_dtype.is_integer()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be integer" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_integer"); } if (int_dtype.is_floating()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be floating" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_floating"); } if (int_dtype.is_object()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be object" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_object"); .. _example-multiindex-is_interval-85: .. dropdown:: is_interval (pd_test_3_all.cpp:3302) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3292 :emphasize-lines: 11 } if (idx.is_categorical()) { throw std::runtime_error("is_categorical() should be false"); } if (idx.is_floating()) { throw std::runtime_error("is_floating() should be false"); } if (idx.is_integer()) { throw std::runtime_error("is_integer() should be false"); } if (idx.is_interval()) { throw std::runtime_error("is_interval() should be false"); } if (idx.is_numeric()) { throw std::runtime_error("is_numeric() should be false"); } if (idx.is_object()) { throw std::runtime_error("is_object() should be false"); } if (idx.holds_integer()) { throw std::runtime_error("holds_integer() should be false"); .. _example-multiindex-is_monotonic_decreasing-86: .. dropdown:: is_monotonic_decreasing (pd_test_1_all.cpp:10203) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10193 :emphasize-lines: 11 } void pd_test_extension_index_monotonicity() { std::cout << "========= monotonicity ========================="; pandas::CategoricalArray arr1({"a", "b", "c"}); pandas::CategoricalIndex idx1(arr1); // Just test that the methods work (result depends on internal ordering) bool inc = idx1.is_monotonic_increasing(); bool dec = idx1.is_monotonic_decreasing(); bool passed = (inc || dec || (!inc && !dec)); // Any result is valid if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_monotonicity() : monotonicity check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_monotonicity failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-is_monotonic_increasing-87: .. dropdown:: is_monotonic_increasing (pd_test_1_all.cpp:10202) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10192 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_monotonicity() { std::cout << "========= monotonicity ========================="; pandas::CategoricalArray arr1({"a", "b", "c"}); pandas::CategoricalIndex idx1(arr1); // Just test that the methods work (result depends on internal ordering) bool inc = idx1.is_monotonic_increasing(); bool dec = idx1.is_monotonic_decreasing(); bool passed = (inc || dec || (!inc && !dec)); // Any result is valid if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_monotonicity() : monotonicity check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_monotonicity failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-is_numeric-88: .. dropdown:: is_numeric (pd_test_3_all.cpp:614) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 604 :emphasize-lines: 11 // ============================================================================ // Category 4: Index Type Checking (IndexDtype) // ============================================================================ void pd_test_3_all_index_dtype_checks() { std::cout << "========= IndexDtype.is_numeric/integer/floating/object() "; // Test with integer index pandas::IndexDtype int_dtype; if (!int_dtype.is_numeric()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be numeric" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_numeric"); } if (!int_dtype.is_integer()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be integer" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_integer"); } if (int_dtype.is_floating()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be floating" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_floating"); .. _example-multiindex-is_object-89: .. dropdown:: is_object (pd_test_3_all.cpp:626) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 616 :emphasize-lines: 11 throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_numeric"); } if (!int_dtype.is_integer()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should be integer" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_integer"); } if (int_dtype.is_floating()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be floating" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_floating"); } if (int_dtype.is_object()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : int should not be object" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: int is_object"); } // Test with float index pandas::IndexDtype float_dtype; if (!float_dtype.is_numeric()) { std::cout << " [FAIL] : in pd_test_3_all_index_dtype_checks() : float should be numeric" << std::endl; throw std::runtime_error("pd_test_3_all_index_dtype_checks failed: float is_numeric"); } .. _example-multiindex-is_unique-90: .. dropdown:: is_unique (pd_test_1_all.cpp:5962) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5952 :emphasize-lines: 11 void pd_test_categorical_index_is_unique() { std::cout << "========= inherited is_unique ========================="; pandas::CategoricalArray arr_unique({"a", "b", "c"}); pandas::CategoricalArray arr_dups({"a", "b", "a"}); pandas::CategoricalIndex idx_unique(arr_unique); pandas::CategoricalIndex idx_dups(arr_dups); bool passed = (idx_unique.is_unique() && !idx_dups.is_unique()); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_is_unique()" << std::endl; throw std::runtime_error("pd_test_categorical_index_is_unique failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_index_hasnans() { std::cout << "========= inherited hasnans ==========================="; .. _example-multiindex-all-91: .. dropdown:: all (pd_test_1_all.cpp:247) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 237 :emphasize-lines: 11 pandas::BooleanArray has_true({ std::optional(false), std::optional(true) }); any_result = has_true.any(); if (!any_result.has_value() || !any_result.value()) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : any() with True" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: any() with True"); } // Test all() pandas::BooleanArray all_true({ std::optional(true), std::optional(true) }); auto all_result = all_true.all(); if (!all_result.has_value() || !all_result.value()) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : all() of all True" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: all() all True"); } .. _example-multiindex-any-92: .. dropdown:: any (pd_test_1_all.cpp:226) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 216 :emphasize-lines: 11 std::cout << " [FAIL] : in pd_test_boolean_array_kleene_not() : ~NA should be NA" << std::endl; throw std::runtime_error("pd_test_boolean_array_kleene_not failed: ~NA"); } std::cout << " -> tests passed" << std::endl; } void pd_test_boolean_array_reductions() { std::cout << "========= BooleanArray: reductions ======================= "; // Test any() pandas::BooleanArray all_false({ std::optional(false), std::optional(false) }); auto any_result = all_false.any(); if (!any_result.has_value() || any_result.value()) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : any() of all False" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: any() all False"); } .. _example-multiindex-argmax-93: .. dropdown:: argmax (pd_test_1_all.cpp:1323) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1313 :emphasize-lines: 11 } // argmin auto min_idx = arr.argmin(); if (!min_idx.has_value() || min_idx.value() != 2) { std::cout << " [FAIL] : argmin should be 2 (2023-01-01)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argmin"); } // argmax auto max_idx = arr.argmax(); if (!max_idx.has_value() || max_idx.value() != 3) { std::cout << " [FAIL] : argmax should be 3 (2023-12-31)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argmax"); } std::cout << " -> tests passed" << std::endl; } void pd_test_datetime_array_unique() { std::cout << "========= DatetimeArray: unique/factorize ======================= "; .. _example-multiindex-argmin-94: .. dropdown:: argmin (pd_test_1_all.cpp:1316) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1306 :emphasize-lines: 11 if (indices.getElementAt({0}) != 2) { std::cout << " [FAIL] : argsort: first should be index 2 (2023-01-01)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argsort first"); } if (indices.getElementAt({3}) != 1) { std::cout << " [FAIL] : argsort: last should be index 1 (NaT)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: NaT position"); } // argmin auto min_idx = arr.argmin(); if (!min_idx.has_value() || min_idx.value() != 2) { std::cout << " [FAIL] : argmin should be 2 (2023-01-01)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argmin"); } // argmax auto max_idx = arr.argmax(); if (!max_idx.has_value() || max_idx.value() != 3) { std::cout << " [FAIL] : argmax should be 3 (2023-12-31)" << std::endl; throw std::runtime_error("pd_test_datetime_array_sorting failed: argmax"); .. _example-multiindex-arrays-95: .. dropdown:: arrays (pd_test_1_all.cpp:10642) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10632 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Set Operations Tests // ============================================================================ void pd_test_extension_index_append() { std::cout << "========= append ========================="; // Use same categories for both arrays (required by CategoricalArray::concat) std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"c", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto appended = idx1.append(idx2); bool passed = (appended.size() == 4); .. _example-multiindex-arrays-96: .. dropdown:: arrays (pd_test_1_all.cpp:10642) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10632 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Set Operations Tests // ============================================================================ void pd_test_extension_index_append() { std::cout << "========= append ========================="; // Use same categories for both arrays (required by CategoricalArray::concat) std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"c", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto appended = idx1.append(idx2); bool passed = (appended.size() == 4); .. _example-multiindex-arrays-97: .. dropdown:: arrays (pd_test_1_all.cpp:10642) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10632 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Set Operations Tests // ============================================================================ void pd_test_extension_index_append() { std::cout << "========= append ========================="; // Use same categories for both arrays (required by CategoricalArray::concat) std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"c", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto appended = idx1.append(idx2); bool passed = (appended.size() == 4); .. _example-multiindex-arrays-98: .. dropdown:: arrays (pd_test_1_all.cpp:10642) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10632 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Set Operations Tests // ============================================================================ void pd_test_extension_index_append() { std::cout << "========= append ========================="; // Use same categories for both arrays (required by CategoricalArray::concat) std::vector cats = {"a", "b", "c", "d"}; pandas::CategoricalArray arr1({"a", "b"}, cats); pandas::CategoricalIndex idx1(arr1); pandas::CategoricalArray arr2({"c", "d"}, cats); pandas::CategoricalIndex idx2(arr2); auto appended = idx1.append(idx2); bool passed = (appended.size() == 4); .. _example-multiindex-codes-99: .. dropdown:: codes (pd_test_1_all.cpp:473) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 463 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_array_codes_property() { std::cout << "========= CategoricalArray: codes property ======================= "; std::vector cats = {"x", "y", "z"}; std::vector codes = {0, 1, 2, 1, 0}; pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); numpy::NDArray arr_codes = arr.codes(); if (arr_codes.getSize() != 5) { std::cout << " [FAIL] : in pd_test_categorical_array_codes_property() : codes size != 5" << std::endl; throw std::runtime_error("pd_test_categorical_array_codes_property failed: codes size != 5"); } // Check codes match for (size_t i = 0; i < codes.size(); ++i) { if (arr_codes.getElementAt({i}) != codes[i]) { std::cout << " [FAIL] : in pd_test_categorical_array_codes_property() : code mismatch at " << i << std::endl; throw std::runtime_error("pd_test_categorical_array_codes_property failed: code mismatch"); .. _example-multiindex-contains-100: .. dropdown:: contains (pd_test_1_all.cpp:2200) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2190 :emphasize-lines: 11 // Test: contains method // ============================================================================ void test_contains() { std::cout << "========= IntervalArray: contains ======================= "; std::vector breaks = {0.0, 1.0, 2.0, 3.0}; // Right-closed intervals: (0, 1], (1, 2], (2, 3] auto arr_right = pandas::IntervalArrayFloat64::from_breaks(breaks, pandas::IntervalClosed::Right); // Test contains(1.0) - should be in interval 0 but not 1 (since 1 is exclusive on left of interval 1) auto contains_1 = arr_right.contains(1.0); // (0, 1] contains 1: yes, (1, 2] contains 1: no (open on left), (2, 3] contains 1: no if (contains_1[0].value_or(false) != true || contains_1[1].value_or(true) != false || contains_1[2].value_or(true) != false) { std::cout << "[FAIL] : in test_contains() : right-closed contains 1.0" << std::endl; return; } // Left-closed intervals: [0, 1), [1, 2), [2, 3) .. _example-multiindex-delete_-101: .. dropdown:: delete_ (pd_test_1_all.cpp:10501) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10491 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_delete() { std::cout << "========= delete_ ========================="; pandas::CategoricalArray arr({"a", "b", "c", "d"}); pandas::CategoricalIndex idx(arr); auto deleted = idx.delete_(1); auto v0 = deleted[0]; auto v1 = deleted[1]; auto v2 = deleted[2]; bool passed = (deleted.size() == 3 && v0.has_value() && *v0 == "a" && v1.has_value() && *v1 == "c" && v2.has_value() && *v2 == "d"); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_delete() : delete_ check failed" << std::endl; .. _example-multiindex-delete_-102: .. dropdown:: delete_ (pd_test_1_all.cpp:10501) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10491 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_delete() { std::cout << "========= delete_ ========================="; pandas::CategoricalArray arr({"a", "b", "c", "d"}); pandas::CategoricalIndex idx(arr); auto deleted = idx.delete_(1); auto v0 = deleted[0]; auto v1 = deleted[1]; auto v2 = deleted[2]; bool passed = (deleted.size() == 3 && v0.has_value() && *v0 == "a" && v1.has_value() && *v1 == "c" && v2.has_value() && *v2 == "d"); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_delete() : delete_ check failed" << std::endl; .. _example-multiindex-dtypes-103: .. dropdown:: dtypes (pd_test_1_all.cpp:6226) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6216 :emphasize-lines: 11 throw std::runtime_error("pd_test_dataframe_properties failed: nbytes should be > 0"); } // Test columns index if (df.columns().size() != 3) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : columns size != 3" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: columns size != 3"); } // Test dtypes auto dtypes = df.dtypes(); if (dtypes.size() != 3) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : dtypes size != 3" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: dtypes size != 3"); } std::cout << " -> tests passed" << std::endl; } // ===================================================================== // Test: Column Access .. _example-multiindex-empty-104: .. dropdown:: empty (pd_test_1_all.cpp:941) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 931 :emphasize-lines: 11 #include "../pandas/pd_config.h" namespace dataframe_tests { namespace dataframe_tests_config { void pd_test_config_version() { std::cout << "========= df_config: version info ======================= "; const char* version = pandas::DataFrameInfo::version(); if (version == nullptr || std::string(version).empty()) { std::cout << "[FAIL] : in pd_test_config_version() : version is null or empty" << std::endl; throw std::runtime_error("pd_test_config_version failed: version is null or empty"); } std::cout << "-> tests passed" << std::endl; } void pd_test_config_na_repr() { std::cout << "========= df_config: NA representation ======================= "; const char* na_repr = pandas::DataFrameConfig::get_na_repr(); if (na_repr == nullptr) { .. _example-multiindex-factorize-105: .. dropdown:: factorize (pd_test_1_all.cpp:1353) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1343 :emphasize-lines: 11 // unique auto uniq = arr.unique(); // Should have: NaT, 2023-01-01, 2023-06-15 (3 unique values) if (uniq.size() != 3) { std::cout << " [FAIL] : unique size should be 3, got " << uniq.size() << std::endl; throw std::runtime_error("pd_test_datetime_array_unique failed: size"); } // factorize auto [codes, uniques] = arr.factorize(); // Codes for NaT should be -1 if (codes.getElementAt({3}) != -1) { std::cout << " [FAIL] : factorize: NaT code should be -1" << std::endl; throw std::runtime_error("pd_test_datetime_array_unique failed: NaT code"); } // Same values should have same codes if (codes.getElementAt({0}) != codes.getElementAt({2})) { std::cout << " [FAIL] : factorize: 2023-01-01 values should have same code" << std::endl; throw std::runtime_error("pd_test_datetime_array_unique failed: same code"); } .. _example-multiindex-format-106: .. dropdown:: format (main.cpp:20) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10 :emphasize-lines: 11 int main() { // Automatically log all output to temp/pd_test_output.log numpy::TestLogger logger("temp/pd_test_output.log"); int res = 0; int res1 = 0; std::string resS = ""; // call all the tests res1 = dataframe_tests::pd_test_main(); resS += std::format(" pd_test_main: {} errors\n", res1); res += res1; std::cout << "\n------------------------- main --------------------------------------------\n"; std::cout << std::endl << "All tests completed. Nb errors = " << res << std::endl; std::cout << "Details: \n" << resS; std::cout << "\n---------------------------------------------------------------------------\n"; return res; } .. _example-multiindex-has_duplicates-107: .. dropdown:: has_duplicates (pd_test_1_all.cpp:10176) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10166 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_uniqueness() { std::cout << "========= uniqueness ========================="; // Unique values pandas::CategoricalArray arr1({"a", "b", "c"}); pandas::CategoricalIndex idx1(arr1); bool passed1 = (idx1.is_unique() && !idx1.has_duplicates()); if (!passed1) { std::cout << " [FAIL] : in pd_test_extension_index_uniqueness() : unique check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_uniqueness failed"); } // With duplicates pandas::CategoricalArray arr2({"a", "b", "a", "c"}); pandas::CategoricalIndex idx2(arr2); bool passed2 = (!idx2.is_unique() && idx2.has_duplicates()); .. _example-multiindex-holds_integer-108: .. dropdown:: holds_integer (pd_test_3_all.cpp:3311) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3301 :emphasize-lines: 11 } if (idx.is_interval()) { throw std::runtime_error("is_interval() should be false"); } if (idx.is_numeric()) { throw std::runtime_error("is_numeric() should be false"); } if (idx.is_object()) { throw std::runtime_error("is_object() should be false"); } if (idx.holds_integer()) { throw std::runtime_error("holds_integer() should be false"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_datetime_index_sort() { std::cout << "========= DatetimeIndex.sort_values() ===================="; pandas::DatetimeIndex idx = pandas::date_range("2024-01-01", "2024-01-05", std::nullopt, "D"); .. _example-multiindex-identical-109: .. dropdown:: identical (pd_test_1_all.cpp:5883) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5873 :emphasize-lines: 11 } void pd_test_categorical_index_identical() { std::cout << "========= identical ==================================="; pandas::CategoricalArray arr({"a", "b"}); pandas::CategoricalIndex idx1(arr, "same_name"); pandas::CategoricalIndex idx2(arr, "same_name"); pandas::CategoricalIndex idx3(arr, "diff_name"); bool passed = (idx1.identical(idx2) && !idx1.identical(idx3)); if (!passed) { std::cout << " [FAIL] : in pd_test_categorical_index_identical()" << std::endl; throw std::runtime_error("pd_test_categorical_index_identical failed"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Inherited Operations Tests .. _example-multiindex-item-110: .. dropdown:: item (pd_test_3_all.cpp:3712) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3702 :emphasize-lines: 11 // Test is_interval (always false for base Index) if (int_idx.is_interval()) { throw std::runtime_error("base Index should not be interval"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_index_item() { std::cout << "========= Index.item() ============================="; pandas::Index idx1({42}); numpy::int64 val = idx1.item(); if (val != 42) { throw std::runtime_error("item() should return 42"); } // Test error for size != 1 pandas::Index idx2({1, 2, 3}); .. _example-multiindex-memory_usage-111: .. dropdown:: memory_usage (pd_test_1_all.cpp:27063) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27053 :emphasize-lines: 11 } std::cout << "====================================== [OK] pd_test_value_counts test suite ========================== " << std::endl; return 0; } } // namespace dataframe_tests // ------------------- pd_test_value_counts.cpp (end) ----------------------------- // ------------------- pd_test_memory_usage.cpp (start) ----------------------------- // Tests for DataFrame.memory_usage() - pandas-compatible memory usage reporting namespace dataframe_tests { namespace dataframe_tests_memory_usage { void pd_test_memory_usage_basic() { std::cout << "========= basic memory_usage ======================="; // Create a simple DataFrame with multiple columns std::map> data; data["A"] = {1.0, 2.0, 3.0, 4.0, 5.0}; .. _example-multiindex-names-112: .. dropdown:: names (pd_test_1_all.cpp:11251) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 11241 :emphasize-lines: 11 pandas::DataFrame df(data); // apply axis=0 applies function to each column auto result = df.apply([](const std::vector& col) { return std::accumulate(col.begin(), col.end(), 0.0); }, 0); bool passed = true; // Plan F·dtype: axis=0 reduce now returns a single "result" column // with the original column names ("A", "B") as the row index. // Sum of A: 1+2+3=6, Sum of B: 4+5+6=15 const auto& result_col = result["result"]; double sum_a = std::stod(result_col.get_value_str(0)); double sum_b = std::stod(result_col.get_value_str(1)); if (!approx_equal(sum_a, 6.0)) { passed = false; std::cout << " [FAIL] : in pd_test_func_apply_dataframe_apply_axis0() : sum A = " << sum_a << std::endl; throw std::runtime_error("pd_test_func_apply_dataframe_apply_axis0 failed: sum A"); } .. _example-multiindex-nlevels-113: .. dropdown:: nlevels (pd_test_1_all.cpp:14138) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14128 :emphasize-lines: 11 // ===================================================================== // Constructor Tests // ===================================================================== void pd_test_multiindex_default_constructor() { std::cout << "========= default constructor ========================= "; pandas::MultiIndex mi; bool passed = (mi.nlevels() == 0) && (mi.size() == 0) && mi.empty(); if (!passed) { std::cout << " [FAIL] : in pd_test_multiindex_default_constructor()" << std::endl; throw std::runtime_error("pd_test_multiindex_default_constructor failed"); } std::cout << "-> tests passed" << std::endl; } void pd_test_multiindex_from_arrays() { .. _example-multiindex-pairs-114: .. dropdown:: pairs (pd_test_5_all.cpp:115042) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 115032 :emphasize-lines: 11 run_mixed_pair ("mixedT.uint16_PLUS_int16",{numpy::uint16(1),numpy::uint16(2)},{numpy::int16(3),numpy::int16(4)}, total_fail, find_id(119)); run_mixed_pair ("mixedT.int32_PLUS_uint32",{numpy::int32(1),numpy::int32(2)},{numpy::uint32(3),numpy::uint32(4)}, total_fail, find_id(120)); run_mixed_pair ("mixedT.uint32_PLUS_int32",{numpy::uint32(1),numpy::uint32(2)},{numpy::int32(3),numpy::int32(4)}, total_fail, find_id(121)); run_mixed_pair ("mixedT.int64_PLUS_uint64",{numpy::int64(1),numpy::int64(2)},{numpy::uint64(3),numpy::uint64(4)}, total_fail, find_id(122)); run_mixed_pair ("mixedT.uint64_PLUS_int64",{numpy::uint64(1),numpy::uint64(2)},{numpy::int64(3),numpy::int64(4)}, total_fail, find_id(123)); run_mixed_pair ("mixedT.int32_PLUS_uint8", {numpy::int32(1),numpy::int32(2)},{numpy::uint8(3),numpy::uint8(4)}, total_fail, find_id(124)); run_mixed_pair ("mixedT.uint8_PLUS_int32", {numpy::uint8(1),numpy::uint8(2)},{numpy::int32(3),numpy::int32(4)}, total_fail, find_id(125)); run_mixed_pair ("mixedT.int64_PLUS_uint32",{numpy::int64(1),numpy::int64(2)},{numpy::uint32(3),numpy::uint32(4)}, total_fail, find_id(126)); run_mixed_pair ("mixedT.uint32_PLUS_int64",{numpy::uint32(1),numpy::uint32(2)},{numpy::int64(3),numpy::int64(4)}, total_fail, find_id(127)); // cross int/float pairs (beyond int64/float64 already in base) run_mixed_pair("mixedT.int8_PLUS_float32", {numpy::int8(1),numpy::int8(2)},{3.0f,4.0f}, total_fail, find_id(128)); run_mixed_pair ("mixedT.float32_PLUS_int8", {1.0f,2.0f},{numpy::int8(3),numpy::int8(4)}, total_fail, find_id(129)); run_mixed_pair("mixedT.int16_PLUS_float64",{numpy::int16(1),numpy::int16(2)},{3.0,4.0}, total_fail, find_id(130)); run_mixed_pair ("mixedT.float64_PLUS_int16",{1.0,2.0},{numpy::int16(3),numpy::int16(4)}, total_fail, find_id(131)); run_mixed_pair("mixedT.int32_PLUS_float32",{numpy::int32(1),numpy::int32(2)},{3.0f,4.0f}, total_fail, find_id(132)); run_mixed_pair ("mixedT.float32_PLUS_int32",{1.0f,2.0f},{numpy::int32(3),numpy::int32(4)}, total_fail, find_id(133)); run_mixed_pair("mixedT.uint16_PLUS_float64",{numpy::uint16(1),numpy::uint16(2)},{3.0,4.0}, total_fail, find_id(134)); run_mixed_pair ("mixedT.float64_PLUS_uint16",{1.0,2.0},{numpy::uint16(3),numpy::uint16(4)}, total_fail, find_id(135)); // same-T baseline for every remaining numeric dtype .. _example-multiindex-putmask-115: .. dropdown:: putmask (pd_test_3_all.cpp:3752) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3742 :emphasize-lines: 11 // Should be at least sizeof index + 5 * sizeof(int64) if (usage < 5 * sizeof(numpy::int64)) { throw std::runtime_error("memory_usage too small"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_index_putmask() { std::cout << "========= Index.putmask() =========================="; pandas::Index idx({1, 2, 3, 4, 5}); numpy::NDArray mask(std::vector{5}); mask.setElementAt({0}, numpy::bool_(true)); mask.setElementAt({1}, numpy::bool_(false)); mask.setElementAt({2}, numpy::bool_(true)); mask.setElementAt({3}, numpy::bool_(false)); mask.setElementAt({4}, numpy::bool_(true)); auto result = idx.putmask(mask, numpy::int64(99)); .. _example-multiindex-ravel-116: .. dropdown:: ravel (pd_test_3_all.cpp:2147) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2137 :emphasize-lines: 11 throw std::runtime_error("memory_usage shallow too small"); } if (deep < shallow) { throw std::runtime_error("memory_usage deep should be >= shallow"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_categorical_ravel_view() { std::cout << "========= CategoricalArray.ravel()/view() ============="; std::vector> values = {"a", "b", "c"}; pandas::CategoricalArray arr(values); auto raveled = arr.ravel(); if (raveled.size() != 3 || !raveled.equals(arr)) { throw std::runtime_error("ravel failed"); } auto viewed = arr.view(); .. _example-multiindex-remove_unused_levels-117: .. dropdown:: remove_unused_levels (pd_test_3_all.cpp:772) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 762 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Category 7: MultiIndex Operations // ============================================================================ void pd_test_3_all_multiindex_remove_unused() { std::cout << "========= MultiIndex.remove_unused_levels() =========="; // Create a MultiIndex with some unused level values std::vector> levels; levels.push_back(std::make_unique>( std::vector{"a", "b", "c", "d"})); // "c" and "d" will be unused levels.push_back(std::make_unique>( std::vector{"x", "y", "z"})); // "z" will be unused // Codes only reference a, b (indices 0, 1) and x, y (indices 0, 1) numpy::NDArray codes0(std::vector{4}); .. _example-multiindex-repeat-118: .. dropdown:: repeat (pd_test_3_all.cpp:2166) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2156 :emphasize-lines: 11 auto viewed = arr.view(); if (viewed.size() != 3 || !viewed.equals(arr)) { throw std::runtime_error("view failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_categorical_repeat() { std::cout << "========= CategoricalArray.repeat() ==================="; std::vector> values = {"a", "b"}; pandas::CategoricalArray arr(values); auto result = arr.repeat(3); if (result.size() != 6 || *result[0] != "a" || *result[2] != "a" || *result[3] != "b" || *result[5] != "b") { throw std::runtime_error("repeat scalar failed"); } .. _example-multiindex-repr-119: .. dropdown:: repr (pd_test_1_all.cpp:10906) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 10896 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_extension_index_repr() { std::cout << "========= repr ========================="; pandas::CategoricalArray arr({"a", "b", "c"}); // Use ExtensionIndex directly to test base class repr pandas::ExtensionIndex idx(arr, "test"); std::string repr_str = idx.repr(); bool passed = (!repr_str.empty() && repr_str.find("ExtensionIndex") != std::string::npos); if (!passed) { std::cout << " [FAIL] : in pd_test_extension_index_repr() : repr check failed" << std::endl; throw std::runtime_error("pd_test_extension_index_repr failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-multiindex-result-120: .. dropdown:: result (pd_test_1_all.cpp:15406) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 15396 :emphasize-lines: 11 data.setElementAt({0}, numpy::datetime64(100LL, numpy::DateTimeUnit::Nanosecond)); data.setElementAt({1}, numpy::datetime64(200LL, numpy::DateTimeUnit::Nanosecond)); numpy::NDArray mask(std::vector{2}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); pandas::DatetimeArray arr(data, mask); pandas::DatetimeIndexBase idx(arr, "original"); // Create join result (int64 values) numpy::NDArray join_result(std::vector{3}); join_result.setElementAt({0}, numpy::int64(500LL)); join_result.setElementAt({1}, numpy::int64(600LL)); join_result.setElementAt({2}, numpy::int64(700LL)); auto new_idx = idx._from_join_target(join_result); bool passed = (new_idx.size() == 3 && new_idx.name().has_value() && *new_idx.name() == "original"); if (!passed) { .. _example-multiindex-result-121: .. dropdown:: result (pd_test_1_all.cpp:15406) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 15396 :emphasize-lines: 11 data.setElementAt({0}, numpy::datetime64(100LL, numpy::DateTimeUnit::Nanosecond)); data.setElementAt({1}, numpy::datetime64(200LL, numpy::DateTimeUnit::Nanosecond)); numpy::NDArray mask(std::vector{2}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); pandas::DatetimeArray arr(data, mask); pandas::DatetimeIndexBase idx(arr, "original"); // Create join result (int64 values) numpy::NDArray join_result(std::vector{3}); join_result.setElementAt({0}, numpy::int64(500LL)); join_result.setElementAt({1}, numpy::int64(600LL)); join_result.setElementAt({2}, numpy::int64(700LL)); auto new_idx = idx._from_join_target(join_result); bool passed = (new_idx.size() == 3 && new_idx.name().has_value() && *new_idx.name() == "original"); if (!passed) { .. _example-multiindex-round-122: .. dropdown:: round (pd_test_1_all.cpp:1688) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1678 :emphasize-lines: 11 void pd_test_floating_array_rounding() { std::cout << "========= FloatingArray: rounding ======================= "; pandas::FloatingArray arr({ std::optional(1.234), std::optional(2.567), std::nullopt }); auto rounded = arr.round(2); if (std::abs(rounded[0].value() - 1.23) > 0.001 || std::abs(rounded[1].value() - 2.57) > 0.001) { std::cout << " [FAIL] : in pd_test_floating_array_rounding() : round(2)" << std::endl; throw std::runtime_error("pd_test_floating_array_rounding failed: round(2)"); } if (!rounded.is_na(2)) { std::cout << " [FAIL] : in pd_test_floating_array_rounding() : round should preserve NA" << std::endl; throw std::runtime_error("pd_test_floating_array_rounding failed: NA preservation"); } .. _example-multiindex-set_codes-123: .. dropdown:: set_codes (pd_test_3_all.cpp:9077) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9067 :emphasize-lines: 11 if (locs.getSize() != 2) { std::cout << " [FAIL] : in pd_test_3_all_multiindex_get_locs() : expected 2 locations" << std::endl; throw std::runtime_error("pd_test_3_all_multiindex_get_locs failed: size"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_multiindex_set_codes() { std::cout << "========= MultiIndex.set_codes() =================="; std::vector> arrays = { {"a", "a", "b", "b"}, {"1", "2", "1", "2"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); // Create new codes numpy::NDArray new_code0({4}); new_code0.setElementAt({0}, 1); // b .. _example-multiindex-set_levels-124: .. dropdown:: set_levels (pd_test_3_all.cpp:9104) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9094 :emphasize-lines: 11 if (mi2.size() != 4) { std::cout << " [FAIL] : in pd_test_3_all_multiindex_set_codes() : size changed" << std::endl; throw std::runtime_error("pd_test_3_all_multiindex_set_codes failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_multiindex_set_levels() { std::cout << "========= MultiIndex.set_levels() ================="; std::vector> arrays = { {"a", "a", "b", "b"}, {"1", "2", "1", "2"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); // Set new levels for level 0 std::vector> new_levels = {{"X", "Y"}}; pandas::MultiIndex mi2 = mi.set_levels(new_levels, 0); .. _example-multiindex-size-125: .. dropdown:: size (pd_test_1_all.cpp:22) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 12 :emphasize-lines: 11 #include "../pandas/pd_boolean_array.h" namespace dataframe_tests { namespace dataframe_tests_boolean_array { void pd_test_boolean_array_constructors() { std::cout << "========= BooleanArray: constructors ======================= "; // Default constructor pandas::BooleanArray arr1; if (arr1.size() != 0) { std::cout << " [FAIL] : in pd_test_boolean_array_constructors() : default constructor size != 0" << std::endl; throw std::runtime_error("pd_test_boolean_array_constructors failed: default constructor size != 0"); } // Initializer list constructor pandas::BooleanArray arr2({ std::optional(true), std::optional(false), std::nullopt, std::optional(true) .. _example-multiindex-slice_indexer-126: .. dropdown:: slice_indexer (pd_test_3_all.cpp:711) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 701 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Category 6: Index Indexer Methods // ============================================================================ void pd_test_3_all_index_indexers() { std::cout << "========= Index.get_indexer_for/non_unique/slice_indexer() "; std::vector vals = {"a", "b", "c", "d", "e"}; pandas::Index idx(vals); // Test get_indexer_for() std::vector target = {"b", "d", "f"}; // "f" doesn't exist numpy::NDArray indexer = idx.get_indexer_for(target); if (indexer.getSize() != 3) { std::cout << " [FAIL] : in pd_test_3_all_index_indexers() : get_indexer_for size mismatch" << std::endl; throw std::runtime_error("pd_test_3_all_index_indexers failed: get_indexer_for size"); .. _example-multiindex-slice_locs-127: .. dropdown:: slice_locs (pd_test_1_all.cpp:18275) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18265 :emphasize-lines: 11 } std::cout << "-> tests passed" << std::endl; } void pd_test_range_index_slice_locs() { std::cout << "========= slice_locs ================================== "; pandas::RangeIndex ri(0, 10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] auto [start_idx, stop_idx] = ri.slice_locs(3, 7); bool passed = (start_idx == 3 && stop_idx == 8); if (!passed) { std::cout << " [FAIL] : slice_locs" << std::endl; throw std::runtime_error("pd_test_range_index_slice_locs failed"); } std::cout << "-> tests passed" << std::endl; } .. _example-multiindex-sort-128: .. dropdown:: sort (pd_test_3_all.cpp:3869) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3859 :emphasize-lines: 11 throw std::runtime_error("last 2 positions should be NaN"); } if (std::abs(result[0] - 3.0) > 0.001) { throw std::runtime_error("shift(-2) [0] should be 3.0"); } std::cout << " -> tests passed" << std::endl; } void pd_test_3_all_index_sort() { std::cout << "========= Index.sort() ============================="; pandas::Index idx({3, 1, 4, 1, 5, 9, 2, 6}); auto result = idx.sort(); if (result[0] != 1 || result[1] != 1 || result[7] != 9) { throw std::runtime_error("sort() not working correctly"); } // Test descending result = idx.sort(false); .. _example-multiindex-sortlevel-129: .. dropdown:: sortlevel (pd_test_1_all.cpp:14676) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 14666 :emphasize-lines: 11 void pd_test_multiindex_sortlevel() { std::cout << "========= sortlevel =================================== "; std::vector> arrays = { {"b", "a", "c"}, {"2", "1", "3"} }; pandas::MultiIndex mi = pandas::MultiIndex::from_arrays(arrays); auto [sorted, indices] = mi.sortlevel(0); bool passed = true; // After sorting by level 0: a, b, c if (sorted[0][0] != "a" || sorted[1][0] != "b" || sorted[2][0] != "c") { std::cout << " [FAIL] : not sorted correctly by level 0" << std::endl; passed = false; } if (!passed) { .. _example-multiindex-str-130: .. dropdown:: str (pd_test_1_all.cpp:7137) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7127 :emphasize-lines: 11 // Test basic info() with stringstream std::map> data = { {"A", {1, 2, 3, 4, 5}}, {"B", {10, 20, 30, 40, 50}}, {"C", {100, 200, 300, 400, 500}} }; pandas::DataFrame df(data); std::ostringstream oss; df.info(oss); std::string output = oss.str(); // Verify key components if (output.find("") == std::string::npos) { std::cout << " [FAIL] : info missing class name" << std::endl; throw std::runtime_error("pd_test_dataframe_info failed: missing class name"); } if (output.find("RangeIndex:") == std::string::npos) { std::cout << " [FAIL] : info missing RangeIndex" << std::endl; throw std::runtime_error("pd_test_dataframe_info failed: missing RangeIndex"); } .. _example-multiindex-truncate-131: .. dropdown:: truncate (pd_test_1_all.cpp:20467) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 20457 :emphasize-lines: 11 std::vector dates = { "2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05" }; df.set_index(std::make_unique>(dates)); // Truncate to keep only dates from 2020-01-02 to 2020-01-04 pandas::DataFrame result = df.truncate("2020-01-02", "2020-01-04"); bool passed = (result.nrows() == 3); if (!passed) { std::cout << " [FAIL] : in pd_test_timeseries_truncate() : expected 3 rows, got " << result.nrows() << std::endl; throw std::runtime_error("pd_test_timeseries_truncate failed"); } std::cout << " -> tests passed" << std::endl;