TimedeltaArray ============== .. cpp:class:: pandas::TimedeltaArray Extension array type for specialized data storage. Example ------- .. code-block:: cpp #include using namespace pandas; // Use TimedeltaArray TimedeltaArray obj; // ... operations ... Constructors ------------ .. list-table:: :widths: 55 25 20 :header-rows: 1 * - Signature - Location - Example * - ``TimedeltaArray(const numpy::NDArray& data, const numpy::NDArray& mask, bool copy = false)`` - pd_timedelta_array.h:208 - :ref:`View ` * - ``TimedeltaArray(const numpy::NDArray& data, const numpy::NDArray& mask, numpy::DateTimeUnit unit, bool copy = false)`` - pd_timedelta_array.h:239 - :ref:`View ` * - ``explicit TimedeltaArray(const numpy::NDArray& data)`` - pd_timedelta_array.h:254 - :ref:`View ` * - ``explicit TimedeltaArray(const std::vector>& values)`` - pd_timedelta_array.h:305 - :ref:`View ` * - ``explicit TimedeltaArray(const std::vector& duration_strings)`` - pd_timedelta_array.h:328 - :ref:`View ` Construction ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static TimedeltaArray from_sequence(const std::vector>& scalars)`` - static TimedeltaArray - pd_timedelta_array.h:550 - Indexing / Selection -------------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::timedelta64 at(size_t index) const`` - numpy::timedelta64 - pd_timedelta_array.h:457 - :ref:`View ` * - ``const numpy::NDArray& mask() const`` - const numpy::NDArray& - pd_timedelta_array.h:437 - :ref:`View ` * - ``TimedeltaArray take(const std::vector& indices, bool allow_fill = false, std::optional fill_value = std::nullopt) const`` - TimedeltaArray - pd_timedelta_array.h:504 - :ref:`View ` Data Manipulation ----------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``TimedeltaArray dropna() const`` - TimedeltaArray - pd_timedelta_array.h:601 - :ref:`View ` Missing Data ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``TimedeltaArray fillna(const numpy::timedelta64& value) const`` - TimedeltaArray - pd_timedelta_array.h:586 - :ref:`View ` * - ``numpy::NDArray isna() const`` - numpy::NDArray - pd_timedelta_array.h:479 - :ref:`View ` * - ``numpy::NDArray notna() const`` - numpy::NDArray - pd_timedelta_array.h:486 - :ref:`View ` Statistics ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``size_t count() const`` - size_t - pd_timedelta_array.h:652 - :ref:`View ` * - ``std::optional max() const`` - std::optional - pd_timedelta_array.h:960 - :ref:`View ` * - ``std::optional min() const`` - std::optional - pd_timedelta_array.h:951 - :ref:`View ` Comparison ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``size_t len() const`` - size_t - pd_timedelta_array.h:408 - :ref:`View ` Sorting ------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::NDArray argsort(bool ascending = true, const std::string& na_position = "last") const`` - numpy::NDArray - pd_timedelta_array.h:877 - :ref:`View ` Combining --------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static TimedeltaArray concat(const std::vector& arrays)`` - static TimedeltaArray - pd_timedelta_array.h:557 - :ref:`View ` I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector> to_pytimedelta() const`` - std::vector> - pd_timedelta_array.h:1104 - :ref:`View ` * - ``std::string to_string() const`` - std::string - pd_timedelta_array.h:1500 - :ref:`View ` Conversion ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``TimedeltaArray copy() const`` - TimedeltaArray - pd_timedelta_array.h:497 - :ref:`View ` Set Operations -------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``TimedeltaArray unique() const`` - TimedeltaArray - pd_timedelta_array.h:815 - :ref:`View ` Type Checking ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``bool is_na(size_t index) const`` - bool - pd_timedelta_array.h:468 - :ref:`View ` * - ``BooleanArray is_negative() const`` - BooleanArray - pd_timedelta_array.h:1218 - :ref:`View ` * - ``BooleanArray is_positive() const`` - BooleanArray - pd_timedelta_array.h:1199 - :ref:`View ` * - ``BooleanArray is_zero() const`` - BooleanArray - pd_timedelta_array.h:1237 - :ref:`View ` Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``TimedeltaArray abs() const`` - TimedeltaArray - pd_timedelta_array.h:1398 - :ref:`View ` * - ``std::optional argmax() const`` - std::optional - pd_timedelta_array.h:929 - :ref:`View ` * - ``std::optional argmin() const`` - std::optional - pd_timedelta_array.h:909 - :ref:`View ` * - ``TimedeltaArray ceil(const std::string& freq) const`` - TimedeltaArray - pd_timedelta_array.h:1446 - :ref:`View ` * - ``DataFrame components_to_dataframe() const`` - DataFrame - pd_timedelta_array.h:1527 - * - ``const numpy::NDArray& data() const`` - const numpy::NDArray& - pd_timedelta_array.h:430 - :ref:`View ` * - ``IntegerArray days() const`` - IntegerArray - pd_timedelta_array.h:973 - :ref:`View ` * - ``void detect_unit()`` - void - pd_timedelta_array.h:1556 - * - ``dtype_type dtype() const`` - dtype_type - pd_timedelta_array.h:366 - :ref:`View ` * - ``bool empty() const`` - bool - pd_timedelta_array.h:401 - :ref:`View ` * - ``std::pair, TimedeltaArray> factorize() const`` - std::pair, TimedeltaArray> - pd_timedelta_array.h:841 - :ref:`View ` * - ``TimedeltaArray floor(const std::string& freq) const`` - TimedeltaArray - pd_timedelta_array.h:1421 - :ref:`View ` * - ``static inline int64_t floor_div(int64_t a, int64_t b)`` - static inline int64_t - pd_timedelta_array.h:161 - * - ``bool has_na() const`` - bool - pd_timedelta_array.h:665 - :ref:`View ` * - ``IntegerArray microseconds() const`` - IntegerArray - pd_timedelta_array.h:1016 - :ref:`View ` * - ``IntegerArray nanoseconds() const`` - IntegerArray - pd_timedelta_array.h:1039 - :ref:`View ` * - ``size_t nbytes() const`` - size_t - pd_timedelta_array.h:380 - :ref:`View ` * - ``constexpr int ndim() const`` - constexpr int - pd_timedelta_array.h:387 - :ref:`View ` * - ``static int64_t parse_freq_to_seconds(const std::string& freq)`` - static int64_t - pd_timedelta_array.h:1560 - * - ``std::string repr() const`` - std::string - pd_timedelta_array.h:1517 - :ref:`View ` * - ``TimedeltaArray round(const std::string& freq) const`` - TimedeltaArray - pd_timedelta_array.h:1471 - :ref:`View ` * - ``IntegerArray seconds() const`` - IntegerArray - pd_timedelta_array.h:992 - :ref:`View ` * - ``std::vector shape() const`` - std::vector - pd_timedelta_array.h:394 - :ref:`View ` * - ``size_t size() const`` - size_t - pd_timedelta_array.h:373 - :ref:`View ` * - ``numpy::timedelta64 td(duration_strings[i])`` - numpy::timedelta64 - pd_timedelta_array.h:340 - :ref:`View ` * - ``FloatingArray total_seconds() const`` - FloatingArray - pd_timedelta_array.h:1077 - :ref:`View ` * - ``numpy::DateTimeUnit unit() const`` - numpy::DateTimeUnit - pd_timedelta_array.h:415 - :ref:`View ` * - ``void validate_arrays()`` - void - pd_timedelta_array.h:1534 - Internal Methods ---------------- *2 internal methods (prefixed with underscore)* Code Examples ------------- The following examples are extracted from the test suite. .. _example-timedeltaarray-timedeltaarray-0: .. dropdown:: TimedeltaArray (pd_test_3_all.cpp:27945) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27935 :emphasize-lines: 11 static pandas::TimedeltaArray make_tda(const std::vector& ns_values) { std::vector> vals; vals.reserve(ns_values.size()); for (double ns : ns_values) { if (std::isnan(ns)) { vals.push_back(std::nullopt); } else { vals.push_back(numpy::timedelta64(static_cast(ns), numpy::DateTimeUnit::Nanosecond)); } } return pandas::TimedeltaArray(vals); } void pd_test_td_decompose_positive() { std::cout << " -- pd_test_td_decompose_positive --" << std::endl; int fail = 0; constexpr int64_t NS = 1000000000LL; int64_t total_ns = (1 * 86400 + 2 * 3600 + 3 * 60 + 4) * NS; auto tda = make_tda({static_cast(total_ns)}); auto days = tda.days(); auto secs = tda.seconds(); .. _example-timedeltaarray-timedeltaarray-1: .. dropdown:: TimedeltaArray (pd_test_3_all.cpp:27945) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27935 :emphasize-lines: 11 static pandas::TimedeltaArray make_tda(const std::vector& ns_values) { std::vector> vals; vals.reserve(ns_values.size()); for (double ns : ns_values) { if (std::isnan(ns)) { vals.push_back(std::nullopt); } else { vals.push_back(numpy::timedelta64(static_cast(ns), numpy::DateTimeUnit::Nanosecond)); } } return pandas::TimedeltaArray(vals); } void pd_test_td_decompose_positive() { std::cout << " -- pd_test_td_decompose_positive --" << std::endl; int fail = 0; constexpr int64_t NS = 1000000000LL; int64_t total_ns = (1 * 86400 + 2 * 3600 + 3 * 60 + 4) * NS; auto tda = make_tda({static_cast(total_ns)}); auto days = tda.days(); auto secs = tda.seconds(); .. _example-timedeltaarray-timedeltaarray-2: .. dropdown:: TimedeltaArray (pd_test_3_all.cpp:27945) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27935 :emphasize-lines: 11 static pandas::TimedeltaArray make_tda(const std::vector& ns_values) { std::vector> vals; vals.reserve(ns_values.size()); for (double ns : ns_values) { if (std::isnan(ns)) { vals.push_back(std::nullopt); } else { vals.push_back(numpy::timedelta64(static_cast(ns), numpy::DateTimeUnit::Nanosecond)); } } return pandas::TimedeltaArray(vals); } void pd_test_td_decompose_positive() { std::cout << " -- pd_test_td_decompose_positive --" << std::endl; int fail = 0; constexpr int64_t NS = 1000000000LL; int64_t total_ns = (1 * 86400 + 2 * 3600 + 3 * 60 + 4) * NS; auto tda = make_tda({static_cast(total_ns)}); auto days = tda.days(); auto secs = tda.seconds(); .. _example-timedeltaarray-timedeltaarray-3: .. dropdown:: TimedeltaArray (pd_test_3_all.cpp:27945) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27935 :emphasize-lines: 11 static pandas::TimedeltaArray make_tda(const std::vector& ns_values) { std::vector> vals; vals.reserve(ns_values.size()); for (double ns : ns_values) { if (std::isnan(ns)) { vals.push_back(std::nullopt); } else { vals.push_back(numpy::timedelta64(static_cast(ns), numpy::DateTimeUnit::Nanosecond)); } } return pandas::TimedeltaArray(vals); } void pd_test_td_decompose_positive() { std::cout << " -- pd_test_td_decompose_positive --" << std::endl; int fail = 0; constexpr int64_t NS = 1000000000LL; int64_t total_ns = (1 * 86400 + 2 * 3600 + 3 * 60 + 4) * NS; auto tda = make_tda({static_cast(total_ns)}); auto days = tda.days(); auto secs = tda.seconds(); .. _example-timedeltaarray-timedeltaarray-4: .. dropdown:: TimedeltaArray (pd_test_3_all.cpp:27945) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 27935 :emphasize-lines: 11 static pandas::TimedeltaArray make_tda(const std::vector& ns_values) { std::vector> vals; vals.reserve(ns_values.size()); for (double ns : ns_values) { if (std::isnan(ns)) { vals.push_back(std::nullopt); } else { vals.push_back(numpy::timedelta64(static_cast(ns), numpy::DateTimeUnit::Nanosecond)); } } return pandas::TimedeltaArray(vals); } void pd_test_td_decompose_positive() { std::cout << " -- pd_test_td_decompose_positive --" << std::endl; int fail = 0; constexpr int64_t NS = 1000000000LL; int64_t total_ns = (1 * 86400 + 2 * 3600 + 3 * 60 + 4) * NS; auto tda = make_tda({static_cast(total_ns)}); auto days = tda.days(); auto secs = tda.seconds(); .. _example-timedeltaarray-at-5: .. dropdown:: at (pd_test_1_all.cpp:6581) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6571 :emphasize-lines: 11 // Test isna/notna with float data { std::map> float_data; float_data["X"] = {1.0, std::nan(""), 3.0}; float_data["Y"] = {4.0, 5.0, std::nan("")}; pandas::DataFrame df_na(float_data); auto na_mask = df_na.isna(); // Row 1, col 0 (X) should be NA if (!na_mask.getElementAt({1, 0})) { std::cout << " [FAIL] : in pd_test_dataframe_manipulation() : isna at (1,0) should be true" << std::endl; throw std::runtime_error("pd_test_dataframe_manipulation failed: isna at (1,0)"); } // Row 2, col 1 (Y) should be NA 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; .. _example-timedeltaarray-mask-6: .. dropdown:: mask (pd_test_1_all.cpp:9119) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9109 :emphasize-lines: 11 void pd_test_datetime_mixin_array_constructor() { std::cout << "========= DatetimeTDMixin array constructor ========================="; // Create DatetimeArray with some values numpy::NDArray data(std::vector{3}); data.setElementAt({0}, numpy::datetime64(1000000000000000000LL, numpy::DateTimeUnit::Nanosecond)); // ~2001 data.setElementAt({1}, numpy::datetime64(1500000000000000000LL, numpy::DateTimeUnit::Nanosecond)); // ~2017 data.setElementAt({2}, numpy::datetime64(1600000000000000000LL, numpy::DateTimeUnit::Nanosecond)); // ~2020 numpy::NDArray mask(std::vector{3}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); mask.setElementAt({2}, numpy::bool_(false)); pandas::DatetimeArray arr(data, mask); pandas::DatetimeTDMixin idx(arr, "timestamps"); bool passed = (idx.size() == 3 && !idx.empty() && idx.name().has_value() && *idx.name() == "timestamps" && idx.inferred_type() == "datetime"); .. _example-timedeltaarray-take-7: .. 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-timedeltaarray-dropna-8: .. 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-timedeltaarray-fillna-9: .. 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-timedeltaarray-isna-10: .. 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-timedeltaarray-notna-11: .. 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-timedeltaarray-count-12: .. dropdown:: count (pd_test_1_all.cpp:66) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 56 :emphasize-lines: 11 if (arr.is_na(0)) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : is_na(0) should be false" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: is_na(0) should be false"); } if (!arr.has_na()) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : has_na() should be true" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: has_na() should be true"); } if (arr.count() != 2) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : count() should be 2" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: count() should be 2"); } std::cout << " -> tests passed" << std::endl; } void pd_test_boolean_array_kleene_and() { std::cout << "========= BooleanArray: Kleene AND ======================= "; .. _example-timedeltaarray-max-13: .. 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-timedeltaarray-min-14: .. 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-timedeltaarray-len-15: .. dropdown:: len (pd_test_3_all.cpp:20867) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 20857 :emphasize-lines: 11 auto title_result = s.str().title(); if (title_result[0] != "Hello World" || title_result[1] != "Hello World" || title_result[2] != "Hello World") { std::cout << " [FAIL] : title() failed" << std::endl; throw std::runtime_error("pd_test_str_capitalize_title: title() failed"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Test str().len() // ============================================================================ void pd_test_str_len() { std::cout << "========= Series.str().len() ============================"; pandas::Series s({"a", "bb", "ccc", ""}); auto lens = s.str().len(); if (lens[0] != 1 || lens[1] != 2 || lens[2] != 3 || lens[3] != 0) { std::cout << " [FAIL] : len() failed" << std::endl; .. _example-timedeltaarray-argsort-16: .. 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-timedeltaarray-concat-17: .. dropdown:: concat (pd_test_1_all.cpp:17717) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 17707 :emphasize-lines: 11 } void pd_test_period_index_concat() { std::cout << "========= concat factory =============================="; std::vector ordinals1 = {0, 1}; std::vector ordinals2 = {2, 3}; pandas::PeriodIndex idx1(ordinals1, "D"); pandas::PeriodIndex idx2(ordinals2, "D"); pandas::PeriodIndex concatenated = pandas::PeriodIndex::concat({idx1, idx2}); bool passed = (concatenated.size() == 4); if (!passed) { std::cout << " [FAIL] : in pd_test_period_index_concat()" << std::endl; throw std::runtime_error("pd_test_period_index_concat failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-timedeltaarray-to_pytimedelta-18: .. dropdown:: to_pytimedelta (pd_test_3_all.cpp:5952) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5942 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Category 21: Timedelta Plan 9 - Missing Functions // ============================================================================ void pd_test_3_all_timedelta_to_pytimedelta() { std::cout << "========= Timedelta.to_pytimedelta() ================="; // Test PyTimedelta struct pandas::PyTimedelta td1; if (td1.days != 0 || td1.seconds != 0 || td1.microseconds != 0) { throw std::runtime_error("PyTimedelta default constructor failed"); } pandas::PyTimedelta td2(5, 3600, 500000); if (td2.days != 5 || td2.seconds != 3600 || td2.microseconds != 500000) { throw std::runtime_error("PyTimedelta parameterized constructor failed"); .. _example-timedeltaarray-to_string-19: .. 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-timedeltaarray-copy-20: .. 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-timedeltaarray-unique-21: .. 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-timedeltaarray-is_na-22: .. dropdown:: is_na (pd_test_1_all.cpp:51) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 41 :emphasize-lines: 11 void pd_test_boolean_array_na_handling() { std::cout << "========= BooleanArray: NA handling ======================= "; pandas::BooleanArray arr({ std::optional(true), std::nullopt, // NA at index 1 std::optional(false) }); if (!arr.is_na(1)) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : is_na(1) should be true" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: is_na(1) should be true"); } if (arr.is_na(0)) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : is_na(0) should be false" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: is_na(0) should be false"); } if (!arr.has_na()) { .. _example-timedeltaarray-is_negative-23: .. dropdown:: is_negative (pd_test_1_all.cpp:4269) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4259 :emphasize-lines: 11 if (!pos[0].has_value() || !pos[0].value()) { std::cout << " [FAIL] : 1 day should be positive" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_positive"); } if (!pos[1].has_value() || pos[1].value()) { std::cout << " [FAIL] : -5 hours should not be positive" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not positive"); } // is_negative auto neg = arr.is_negative(); if (!neg[1].has_value() || !neg[1].value()) { std::cout << " [FAIL] : -5 hours should be negative" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_negative"); } if (!neg[0].has_value() || neg[0].value()) { std::cout << " [FAIL] : 1 day should not be negative" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not negative"); } // is_zero .. _example-timedeltaarray-is_positive-24: .. dropdown:: is_positive (pd_test_1_all.cpp:4258) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4248 :emphasize-lines: 11 std::cout << "========= TimedeltaArray: boolean properties ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(1, numpy::DateTimeUnit::Day)), // positive std::optional(numpy::timedelta64(-5, numpy::DateTimeUnit::Hour)), // negative std::optional(numpy::timedelta64(0, numpy::DateTimeUnit::Second)), // zero std::nullopt }); // is_positive auto pos = arr.is_positive(); if (!pos[0].has_value() || !pos[0].value()) { std::cout << " [FAIL] : 1 day should be positive" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_positive"); } if (!pos[1].has_value() || pos[1].value()) { std::cout << " [FAIL] : -5 hours should not be positive" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not positive"); } // is_negative .. _example-timedeltaarray-is_zero-25: .. dropdown:: is_zero (pd_test_1_all.cpp:4280) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4270 :emphasize-lines: 11 if (!neg[1].has_value() || !neg[1].value()) { std::cout << " [FAIL] : -5 hours should be negative" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_negative"); } if (!neg[0].has_value() || neg[0].value()) { std::cout << " [FAIL] : 1 day should not be negative" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not negative"); } // is_zero auto zero = arr.is_zero(); if (!zero[2].has_value() || !zero[2].value()) { std::cout << " [FAIL] : 0 seconds should be zero" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_zero"); } // NA should propagate if (pos[3].has_value() || neg[3].has_value() || zero[3].has_value()) { std::cout << " [FAIL] : NaT should propagate to boolean props" << std::endl; throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: NaT propagation"); } .. _example-timedeltaarray-abs-26: .. dropdown:: abs (pd_test_1_all.cpp:283) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 273 :emphasize-lines: 11 std::optional(true) }); auto s = arr.sum(); if (!s.has_value() || s.value() != 3) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : sum should be 3" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: sum"); } auto m = arr.mean(); if (!m.has_value() || std::abs(m.value() - 0.75) > 0.001) { std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : mean should be 0.75" << std::endl; throw std::runtime_error("pd_test_boolean_array_reductions failed: mean"); } std::cout << " -> tests passed" << std::endl; } void pd_test_boolean_array_dtype() { std::cout << "========= BooleanArray: dtype ======================= "; .. _example-timedeltaarray-argmax-27: .. 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-timedeltaarray-argmin-28: .. 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-timedeltaarray-ceil-29: .. dropdown:: ceil (pd_test_1_all.cpp:4949) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4939 :emphasize-lines: 11 throw std::runtime_error("pd_test_arithmetic_series_round failed: round failed"); } auto f = a.floor(); passed = std::abs(f[0] - 1.0) < 0.001 && std::abs(f[2] - 3.0) < 0.001 && std::abs(f[3] - (-2.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : floor failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: floor failed"); } auto c = a.ceil(); passed = std::abs(c[0] - 2.0) < 0.001 && std::abs(c[2] - 4.0) < 0.001 && std::abs(c[3] - (-1.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : ceil failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: ceil failed"); } // Round with decimals pandas::Series b({1.234, 2.567, 3.891}); auto r2 = b.round(2); passed = std::abs(r2[0] - 1.23) < 0.001 && std::abs(r2[1] - 2.57) < 0.001; .. _example-timedeltaarray-data-30: .. dropdown:: data (pd_test_1_all.cpp:9114) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9104 :emphasize-lines: 11 throw std::runtime_error("pd_test_datetime_mixin_default_constructor failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_datetime_mixin_array_constructor() { std::cout << "========= DatetimeTDMixin array constructor ========================="; // Create DatetimeArray with some values numpy::NDArray data(std::vector{3}); data.setElementAt({0}, numpy::datetime64(1000000000000000000LL, numpy::DateTimeUnit::Nanosecond)); // ~2001 data.setElementAt({1}, numpy::datetime64(1500000000000000000LL, numpy::DateTimeUnit::Nanosecond)); // ~2017 data.setElementAt({2}, numpy::datetime64(1600000000000000000LL, numpy::DateTimeUnit::Nanosecond)); // ~2020 numpy::NDArray mask(std::vector{3}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); mask.setElementAt({2}, numpy::bool_(false)); pandas::DatetimeArray arr(data, mask); .. _example-timedeltaarray-days-31: .. dropdown:: days (pd_test_1_all.cpp:4160) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4150 :emphasize-lines: 11 void pd_test_timedelta_array_component_days() { std::cout << "========= TimedeltaArray: days component ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(3, numpy::DateTimeUnit::Day)), std::nullopt, std::optional(numpy::timedelta64(36, numpy::DateTimeUnit::Hour)) // 1.5 days }); auto days_arr = arr.days(); auto d0 = days_arr[0]; if (!d0.has_value() || d0.value() != 3) { std::cout << " [FAIL] : days[0] should be 3" << std::endl; throw std::runtime_error("pd_test_timedelta_array_component_days failed: days[0]"); } auto d1 = days_arr[1]; if (d1.has_value()) { std::cout << " [FAIL] : days[1] should be NA (NaT)" << std::endl; .. _example-timedeltaarray-dtype-32: .. dropdown:: dtype (pd_test_1_all.cpp:295) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 285 :emphasize-lines: 11 throw std::runtime_error("pd_test_boolean_array_reductions failed: mean"); } std::cout << " -> tests passed" << std::endl; } void pd_test_boolean_array_dtype() { std::cout << "========= BooleanArray: dtype ======================= "; pandas::BooleanArray arr; if (arr.dtype().name() != "boolean") { std::cout << " [FAIL] : in pd_test_boolean_array_dtype() : dtype name should be 'boolean'" << std::endl; throw std::runtime_error("pd_test_boolean_array_dtype failed: dtype name"); } if (arr.dtype().kind() != "b") { std::cout << " [FAIL] : in pd_test_boolean_array_dtype() : dtype kind should be 'b'" << std::endl; throw std::runtime_error("pd_test_boolean_array_dtype failed: dtype kind"); } std::cout << " -> tests passed" << std::endl; .. _example-timedeltaarray-empty-33: .. 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-timedeltaarray-factorize-34: .. 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-timedeltaarray-floor-35: .. dropdown:: floor (pd_test_1_all.cpp:4942) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4932 :emphasize-lines: 11 pandas::Series a({1.4, 2.5, 3.6, -1.4, -2.5}); auto r = a.round(); bool passed = std::abs(r[0] - 1.0) < 0.001 && std::abs(r[2] - 4.0) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : round failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: round failed"); } auto f = a.floor(); passed = std::abs(f[0] - 1.0) < 0.001 && std::abs(f[2] - 3.0) < 0.001 && std::abs(f[3] - (-2.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : floor failed" << std::endl; throw std::runtime_error("pd_test_arithmetic_series_round failed: floor failed"); } auto c = a.ceil(); passed = std::abs(c[0] - 2.0) < 0.001 && std::abs(c[2] - 4.0) < 0.001 && std::abs(c[3] - (-1.0)) < 0.001; if (!passed) { std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : ceil failed" << std::endl; .. _example-timedeltaarray-has_na-36: .. dropdown:: has_na (pd_test_1_all.cpp:61) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 51 :emphasize-lines: 11 if (!arr.is_na(1)) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : is_na(1) should be true" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: is_na(1) should be true"); } if (arr.is_na(0)) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : is_na(0) should be false" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: is_na(0) should be false"); } if (!arr.has_na()) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : has_na() should be true" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: has_na() should be true"); } if (arr.count() != 2) { std::cout << " [FAIL] : in pd_test_boolean_array_na_handling() : count() should be 2" << std::endl; throw std::runtime_error("pd_test_boolean_array_na_handling failed: count() should be 2"); } std::cout << " -> tests passed" << std::endl; .. _example-timedeltaarray-microseconds-37: .. dropdown:: microseconds (pd_test_1_all.cpp:19701) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 19691 :emphasize-lines: 11 constexpr int64_t NS_PER_US = 1000LL; std::vector> values = { make_td(0), // 0 us make_td(500 * NS_PER_US), // 500 us make_td(NS_PER_SEC + 100 * NS_PER_US) // 1 sec + 100 us }; pandas::TimedeltaArray arr(values); pandas::TimedeltaIndex idx(arr); auto microseconds = idx.microseconds(); bool passed = (microseconds.size() == 3); if (!passed) { std::cout << " [FAIL] : in pd_test_timedelta_index_microseconds()" << std::endl; throw std::runtime_error("pd_test_timedelta_index_microseconds failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-timedeltaarray-nanoseconds-38: .. dropdown:: nanoseconds (pd_test_1_all.cpp:9379) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9369 :emphasize-lines: 11 std::cout << " [FAIL] : in pd_test_datetime_as_unit() : as_unit check failed" << std::endl; throw std::runtime_error("pd_test_datetime_as_unit failed"); } std::cout << " -> tests passed" << std::endl; } void pd_test_timedelta_as_unit() { std::cout << "========= TimedeltaTDMixin as_unit ========================="; // Create index in nanoseconds (1 hour, 2 hours) numpy::NDArray data(std::vector{2}); data.setElementAt({0}, numpy::timedelta64(3600000000000LL, numpy::DateTimeUnit::Nanosecond)); // 1 hour data.setElementAt({1}, numpy::timedelta64(7200000000000LL, numpy::DateTimeUnit::Nanosecond)); // 2 hours numpy::NDArray mask(std::vector{2}); mask.setElementAt({0}, numpy::bool_(false)); mask.setElementAt({1}, numpy::bool_(false)); pandas::TimedeltaArray arr(data, mask); pandas::TimedeltaTDMixin idx(arr, "durations"); .. _example-timedeltaarray-nbytes-39: .. dropdown:: nbytes (pd_test_1_all.cpp:6214) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6204 :emphasize-lines: 11 } // Test empty DataFrame pandas::DataFrame empty_df; if (!empty_df.empty()) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : should be empty" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: should be empty"); } // Test nbytes > 0 for non-empty if (df.nbytes() == 0) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : nbytes should be > 0" << std::endl; 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"); } .. _example-timedeltaarray-ndim-40: .. dropdown:: ndim (pd_test_1_all.cpp:6195) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6185 :emphasize-lines: 11 pandas::DataFrame df(data); // Test shape auto shape = df.shape(); if (shape.size() != 2 || shape[0] != 4 || shape[1] != 3) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : shape mismatch" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: shape mismatch"); } // Test ndim if (df.ndim() != 2) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : ndim != 2" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: ndim != 2"); } // Test empty if (df.empty()) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : should not be empty" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: should not be empty"); } .. _example-timedeltaarray-repr-41: .. 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-timedeltaarray-round-42: .. 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-timedeltaarray-seconds-43: .. dropdown:: seconds (pd_test_1_all.cpp:4192) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4182 :emphasize-lines: 11 void pd_test_timedelta_array_component_seconds() { std::cout << "========= TimedeltaArray: seconds component ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(90, numpy::DateTimeUnit::Second)), // 90 secs std::optional(numpy::timedelta64(3700, numpy::DateTimeUnit::Second)), // 1h + 100s std::nullopt }); auto secs = arr.seconds(); auto s0 = secs[0]; if (!s0.has_value() || s0.value() != 90) { std::cout << " [FAIL] : seconds[0] should be 90" << std::endl; throw std::runtime_error("pd_test_timedelta_array_component_seconds failed: seconds[0]"); } auto s1 = secs[1]; if (!s1.has_value() || s1.value() != 3700) { std::cout << " [FAIL] : seconds[1] should be 3700" << std::endl; .. _example-timedeltaarray-shape-44: .. dropdown:: shape (pd_test_1_all.cpp:6188) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6178 :emphasize-lines: 11 std::cout << "========= properties ======================="; std::map> data; data["A"] = {1.0, 2.0, 3.0, 4.0}; data["B"] = {5.0, 6.0, 7.0, 8.0}; data["C"] = {9.0, 10.0, 11.0, 12.0}; pandas::DataFrame df(data); // Test shape auto shape = df.shape(); if (shape.size() != 2 || shape[0] != 4 || shape[1] != 3) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : shape mismatch" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: shape mismatch"); } // Test ndim if (df.ndim() != 2) { std::cout << " [FAIL] : in pd_test_dataframe_properties() : ndim != 2" << std::endl; throw std::runtime_error("pd_test_dataframe_properties failed: ndim != 2"); } .. _example-timedeltaarray-size-45: .. 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-timedeltaarray-td-46: .. dropdown:: td (pd_test_1_all.cpp:9535) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9525 :emphasize-lines: 11 } std::cout << " -> tests passed" << std::endl; } void pd_test_timedelta_rounding_params() { std::cout << "========= Timedelta rounding with DST params ====="; // Create a Timedelta: 1h 30m 45s // Constructor is: (days, hours, minutes, seconds, ...) pandas::Timedelta td(0, 1, 30, 45); // 0 days, 1h, 30m, 45s // Test floor with ambiguous/nonexistent params pandas::Timedelta floored = td.floor("h", "raise", "raise"); std::cout << std::endl << " floor('h'): " << floored.toString(); // Test ceil with ambiguous/nonexistent params pandas::Timedelta ceiled = td.ceil("h", "raise", "raise"); std::cout << std::endl << " ceil('h'): " << ceiled.toString(); // Test round with ambiguous/nonexistent params .. _example-timedeltaarray-total_seconds-47: .. dropdown:: total_seconds (pd_test_1_all.cpp:4224) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4214 :emphasize-lines: 11 void pd_test_timedelta_array_total_seconds() { std::cout << "========= TimedeltaArray: total_seconds ======================= "; pandas::TimedeltaArray arr({ std::optional(numpy::timedelta64(1, numpy::DateTimeUnit::Day)), std::optional(numpy::timedelta64(1, numpy::DateTimeUnit::Hour)), std::nullopt }); auto total = arr.total_seconds(); auto t0 = total[0]; if (!t0.has_value() || std::abs(t0.value() - 86400.0) > 0.001) { std::cout << " [FAIL] : total_seconds[0] should be 86400" << std::endl; throw std::runtime_error("pd_test_timedelta_array_total_seconds failed: total_seconds[0]"); } auto t1 = total[1]; if (!t1.has_value() || std::abs(t1.value() - 3600.0) > 0.001) { std::cout << " [FAIL] : total_seconds[1] should be 3600" << std::endl; .. _example-timedeltaarray-unit-48: .. dropdown:: unit (pd_test_1_all.cpp:9284) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9274 :emphasize-lines: 11 data.setElementAt({0}, numpy::datetime64(1000LL, numpy::DateTimeUnit::Nanosecond)); data.setElementAt({1}, numpy::datetime64(2000LL, 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::DatetimeTDMixin idx(arr); std::string unit = idx.unit(); bool passed = (unit == "ns"); // nanosecond if (!passed) { std::cout << " [FAIL] : in pd_test_datetime_unit_property() : unit property check failed, got '" << unit << "'" << std::endl; throw std::runtime_error("pd_test_datetime_unit_property failed"); } std::cout << " -> tests passed" << std::endl; }