CategoricalAccessor =================== .. cpp:class:: pandas::CategoricalAccessor pandas C++ class. Example ------- .. code-block:: cpp #include using namespace pandas; // Use CategoricalAccessor CategoricalAccessor obj; // ... operations ... Data Manipulation ----------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector rename_categories(const std::vector& new_categories) const`` - std::vector - pd_categorical_accessor.h:142 - :ref:`View ` * - ``std::vector rename_categories(const std::map& mapping) const`` - std::vector - pd_categorical_accessor.h:157 - :ref:`View ` Arithmetic ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector add_categories(const std::vector& new_categories) const`` - std::vector - pd_categorical_accessor.h:95 - :ref:`View ` I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``CategoricalArray to_categorical_array() const`` - CategoricalArray - pd_categorical_accessor.h:213 - :ref:`View ` Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``CategoricalAccessor as_ordered() const`` - CategoricalAccessor - pd_categorical_accessor.h:229 - :ref:`View ` * - ``CategoricalAccessor as_unordered() const`` - CategoricalAccessor - pd_categorical_accessor.h:237 - :ref:`View ` * - ``std::vector categories() const`` - std::vector - pd_categorical_accessor.h:79 - :ref:`View ` * - ``std::vector codes() const`` - std::vector - pd_categorical_accessor.h:84 - :ref:`View ` * - ``void compute_if_needed() const`` - void - pd_categorical_accessor.h:35 - * - ``bool ordered() const`` - bool - pd_categorical_accessor.h:89 - :ref:`View ` * - ``const ParentType& parent() const`` - const ParentType& - pd_categorical_accessor.h:76 - * - ``explicit CategoricalAccessor(const ParentType& parent) : parent_(parent)`` - explicit CategoricalAccessor(const ParentType& parent) : - pd_categorical_accessor.h:73 - * - ``std::vector remove_categories(const std::vector& removals) const`` - std::vector - pd_categorical_accessor.h:107 - :ref:`View ` * - ``std::vector remove_unused_categories() const`` - std::vector - pd_categorical_accessor.h:119 - :ref:`View ` * - ``std::vector reorder_categories( const std::vector& new_categories, std::optional ordered = std::nullopt) const`` - std::vector - pd_categorical_accessor.h:177 - :ref:`View ` * - ``CategoricalAccessor result(\*this)`` - CategoricalAccessor - pd_categorical_accessor.h:230 - :ref:`View ` * - ``CategoricalAccessor result(\*this)`` - CategoricalAccessor - pd_categorical_accessor.h:238 - :ref:`View ` * - ``std::vector set_categories( const std::vector& new_categories, std::optional ordered = std::nullopt, bool rename = false) const`` - std::vector - pd_categorical_accessor.h:199 - :ref:`View ` Code Examples ------------- The following examples are extracted from the test suite. .. _example-categoricalaccessor-rename_categories-0: .. dropdown:: rename_categories (pd_test_1_all.cpp:655) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 645 :emphasize-lines: 11 void pd_test_categorical_array_rename_categories() { std::cout << "========= CategoricalArray: rename_categories ======================= "; std::vector cats = {"a", "b"}; std::vector codes = {0, 1, 0}; // a, b, a pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); // Rename categories std::vector new_names = {"alpha", "beta"}; pandas::CategoricalArray result = arr.rename_categories(new_names); // Check categories are renamed const std::vector& result_cats = result.categories(); if (result_cats[0] != "alpha" || result_cats[1] != "beta") { std::cout << " [FAIL] : in pd_test_categorical_array_rename_categories() : categories not renamed" << std::endl; throw std::runtime_error("pd_test_categorical_array_rename_categories failed: categories not renamed"); } // Values should now be renamed std::optional val = result[0]; .. _example-categoricalaccessor-rename_categories-1: .. dropdown:: rename_categories (pd_test_1_all.cpp:655) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 645 :emphasize-lines: 11 void pd_test_categorical_array_rename_categories() { std::cout << "========= CategoricalArray: rename_categories ======================= "; std::vector cats = {"a", "b"}; std::vector codes = {0, 1, 0}; // a, b, a pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); // Rename categories std::vector new_names = {"alpha", "beta"}; pandas::CategoricalArray result = arr.rename_categories(new_names); // Check categories are renamed const std::vector& result_cats = result.categories(); if (result_cats[0] != "alpha" || result_cats[1] != "beta") { std::cout << " [FAIL] : in pd_test_categorical_array_rename_categories() : categories not renamed" << std::endl; throw std::runtime_error("pd_test_categorical_array_rename_categories failed: categories not renamed"); } // Values should now be renamed std::optional val = result[0]; .. _example-categoricalaccessor-add_categories-2: .. dropdown:: add_categories (pd_test_1_all.cpp:555) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 545 :emphasize-lines: 11 } void pd_test_categorical_array_add_categories() { std::cout << "========= CategoricalArray: add_categories ======================= "; std::vector cats = {"a", "b"}; std::vector codes = {0, 1, 0}; pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); // Add new categories pandas::CategoricalArray result = arr.add_categories({"c", "d"}); if (result.categories().size() != 4) { std::cout << " [FAIL] : in pd_test_categorical_array_add_categories() : new categories size != 4" << std::endl; throw std::runtime_error("pd_test_categorical_array_add_categories failed: new categories size != 4"); } // Original values should be preserved std::optional val = result[0]; if (!val.has_value() || *val != "a") { std::cout << " [FAIL] : in pd_test_categorical_array_add_categories() : value not preserved" << std::endl; throw std::runtime_error("pd_test_categorical_array_add_categories failed: value not preserved"); .. _example-categoricalaccessor-to_categorical_array-3: .. dropdown:: to_categorical_array (pd_test_3_all.cpp:28619) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 28609 :emphasize-lines: 11 fail += cgo_check(r3.ordered() == arr.ordered(), "ordered inherited"); if (fail == 0) std::cout << " OK" << std::endl; if (fail != 0) throw std::runtime_error("pd_test_cat_set_categories_ordered failed"); } void pd_test_cat_to_array_bridge() { std::cout << " -- pd_test_cat_to_array_bridge --" << std::endl; int fail = 0; pandas::Series s({"a", "b", "c", "a"}, "x"); auto acc = s.cat(); auto arr = acc.to_categorical_array(); fail += cgo_check(arr.size() == 4, "size"); const auto& cats = arr.categories(); fail += cgo_check(cats.size() == 3, "3 categories"); // Now set_categories via accessor delegation should filter auto newc = acc.set_categories({"a", "b"}); fail += cgo_check(newc.size() == 2, "set_categories delegation returned 2"); if (fail == 0) std::cout << " OK" << std::endl; if (fail != 0) throw std::runtime_error("pd_test_cat_to_array_bridge failed"); } .. _example-categoricalaccessor-as_ordered-4: .. dropdown:: as_ordered (pd_test_1_all.cpp:791) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 781 :emphasize-lines: 11 unordered.min(); } catch (const std::exception&) { threw = true; } if (!threw) { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : unordered min should throw" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: unordered min should throw"); } // Test as_ordered / as_unordered pandas::CategoricalArray reordered = unordered.as_ordered(); if (!reordered.ordered()) { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : as_ordered failed" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: as_ordered failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_array_comparisons() { std::cout << "========= CategoricalArray: comparisons ======================= "; .. _example-categoricalaccessor-as_unordered-5: .. dropdown:: as_unordered (pd_test_1_all.cpp:778) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 768 :emphasize-lines: 11 } // 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(); } catch (const std::exception&) { threw = true; } if (!threw) { std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : unordered min should throw" << std::endl; throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: unordered min should throw"); } .. _example-categoricalaccessor-categories-6: .. dropdown:: categories (pd_test_1_all.cpp:389) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 379 :emphasize-lines: 11 std::vector> vals = { std::optional("low"), std::optional("high"), std::optional("medium") }; pandas::CategoricalArray arr3(vals, cats, true); // ordered if (!arr3.ordered()) { std::cout << " [FAIL] : in pd_test_categorical_array_constructors() : should be ordered" << std::endl; throw std::runtime_error("pd_test_categorical_array_constructors failed: should be ordered"); } if (arr3.categories().size() != 3) { std::cout << " [FAIL] : in pd_test_categorical_array_constructors() : categories size != 3" << std::endl; throw std::runtime_error("pd_test_categorical_array_constructors failed: categories size != 3"); } std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_array_from_codes() { std::cout << "========= CategoricalArray: from_codes ======================= "; .. _example-categoricalaccessor-codes-7: .. 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-categoricalaccessor-ordered-8: .. dropdown:: ordered (pd_test_1_all.cpp:359) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 349 :emphasize-lines: 11 void pd_test_categorical_array_constructors() { std::cout << "========= CategoricalArray: constructors ======================= "; // Default constructor pandas::CategoricalArray arr1; if (arr1.size() != 0) { std::cout << " [FAIL] : in pd_test_categorical_array_constructors() : default constructor size != 0" << std::endl; throw std::runtime_error("pd_test_categorical_array_constructors failed: default constructor size != 0"); } if (arr1.ordered()) { std::cout << " [FAIL] : in pd_test_categorical_array_constructors() : default should be unordered" << std::endl; throw std::runtime_error("pd_test_categorical_array_constructors failed: default should be unordered"); } // Constructor from values (infer categories) std::vector> values = { std::optional("a"), std::optional("b"), std::optional("a"), std::optional("c") .. _example-categoricalaccessor-remove_categories-9: .. dropdown:: remove_categories (pd_test_1_all.cpp:591) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 581 :emphasize-lines: 11 } void pd_test_categorical_array_remove_categories() { std::cout << "========= CategoricalArray: remove_categories ======================= "; std::vector cats = {"a", "b", "c"}; std::vector codes = {0, 1, 2, 1}; // a, b, c, b pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); // Remove 'c' - values with 'c' become NA pandas::CategoricalArray result = arr.remove_categories({"c"}); if (result.categories().size() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_remove_categories() : categories size != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_remove_categories failed: categories size != 2"); } // Element at index 2 should now be NA (was 'c') if (!result.is_na(2)) { std::cout << " [FAIL] : in pd_test_categorical_array_remove_categories() : removed category should be NA" << std::endl; throw std::runtime_error("pd_test_categorical_array_remove_categories failed: removed category should be NA"); .. _example-categoricalaccessor-remove_unused_categories-10: .. dropdown:: remove_unused_categories (pd_test_1_all.cpp:737) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 727 :emphasize-lines: 11 std::cout << " -> tests passed" << std::endl; } void pd_test_categorical_array_remove_unused_categories() { std::cout << "========= CategoricalArray: remove_unused_categories ======================= "; std::vector cats = {"a", "b", "c", "d"}; std::vector codes = {0, 0, 2}; // a, a, c (b and d unused) pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); pandas::CategoricalArray result = arr.remove_unused_categories(); // Only 'a' and 'c' should remain if (result.categories().size() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_remove_unused_categories() : categories size != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_remove_unused_categories failed: categories size != 2"); } // Values should be preserved std::optional val0 = result[0]; std::optional val2 = result[2]; .. _example-categoricalaccessor-reorder_categories-11: .. dropdown:: reorder_categories (pd_test_1_all.cpp:695) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 685 :emphasize-lines: 11 void pd_test_categorical_array_reorder_categories() { std::cout << "========= CategoricalArray: reorder_categories ======================= "; std::vector cats = {"a", "b", "c"}; std::vector codes = {0, 1, 2}; // a, b, c pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); // Reorder categories std::vector new_order = {"c", "b", "a"}; pandas::CategoricalArray result = arr.reorder_categories(new_order); // Check categories are reordered const std::vector& result_cats = result.categories(); if (result_cats[0] != "c" || result_cats[1] != "b" || result_cats[2] != "a") { std::cout << " [FAIL] : in pd_test_categorical_array_reorder_categories() : categories not reordered" << std::endl; throw std::runtime_error("pd_test_categorical_array_reorder_categories failed: categories not reordered"); } // Values should be preserved std::optional val0 = result[0]; .. _example-categoricalaccessor-result-12: .. 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-categoricalaccessor-result-13: .. 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-categoricalaccessor-set_categories-14: .. dropdown:: set_categories (pd_test_1_all.cpp:623) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 613 :emphasize-lines: 11 void pd_test_categorical_array_set_categories() { std::cout << "========= CategoricalArray: set_categories ======================= "; std::vector cats = {"a", "b"}; std::vector codes = {0, 1, 0}; // a, b, a pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats); // Set new categories (values not in new categories become NA) std::vector new_cats = {"a", "c"}; // 'b' removed, 'c' added pandas::CategoricalArray result = arr.set_categories(new_cats); if (result.categories().size() != 2) { std::cout << " [FAIL] : in pd_test_categorical_array_set_categories() : categories size != 2" << std::endl; throw std::runtime_error("pd_test_categorical_array_set_categories failed: categories size != 2"); } // Element at index 1 should be NA (was 'b', now not in categories) if (!result.is_na(1)) { std::cout << " [FAIL] : in pd_test_categorical_array_set_categories() : 'b' value should be NA" << std::endl; throw std::runtime_error("pd_test_categorical_array_set_categories failed: 'b' value should be NA");