DatetimeArray ============= .. cpp:class:: pandas::DatetimeArray Extension array type for specialized data storage. Example ------- .. code-block:: cpp #include using namespace pandas; // Use DatetimeArray DatetimeArray obj; // ... operations ... Constructors ------------ .. list-table:: :widths: 55 25 20 :header-rows: 1 * - Signature - Location - Example * - ``DatetimeArray(const numpy::NDArray& data, const numpy::NDArray& mask, std::shared_ptr tz = nullptr, bool copy = false)`` - pd_datetime_array.h:97 - * - ``DatetimeArray(const numpy::NDArray& data, const numpy::NDArray& mask, numpy::DateTimeUnit unit, std::shared_ptr tz = nullptr, bool copy = false)`` - pd_datetime_array.h:123 - * - ``explicit DatetimeArray(const numpy::NDArray& data, std::shared_ptr tz = nullptr)`` - pd_datetime_array.h:141 - * - ``explicit DatetimeArray(const std::vector>& values, std::shared_ptr tz = nullptr)`` - pd_datetime_array.h:189 - * - ``explicit DatetimeArray(const std::vector& iso_strings, std::shared_ptr tz = nullptr)`` - pd_datetime_array.h:210 - Construction ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static DatetimeArray from_sequence(const std::vector>& scalars, std::shared_ptr tz = nullptr)`` - static DatetimeArray - pd_datetime_array.h:486 - * - ``static DatetimeArray from_timestamps( const std::vector>& vec, const std::string& uniform_tz = "")`` - DatetimeArray - pd_datetime_array.h:256 - :ref:`View ` Indexing / Selection -------------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::datetime64 at(size_t index) const`` - numpy::datetime64 - pd_datetime_array.h:393 - :ref:`View ` * - ``const numpy::NDArray& mask() const`` - const numpy::NDArray& - pd_datetime_array.h:373 - :ref:`View ` * - ``DatetimeArray take(const std::vector& indices, bool allow_fill = false, std::optional fill_value = std::nullopt) const`` - DatetimeArray - pd_datetime_array.h:440 - :ref:`View ` Data Manipulation ----------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeArray dropna() const`` - DatetimeArray - pd_datetime_array.h:538 - :ref:`View ` Missing Data ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeArray fillna(const numpy::datetime64& value) const`` - DatetimeArray - pd_datetime_array.h:523 - :ref:`View ` * - ``numpy::NDArray isna() const`` - numpy::NDArray - pd_datetime_array.h:415 - :ref:`View ` * - ``numpy::NDArray notna() const`` - numpy::NDArray - pd_datetime_array.h:422 - :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_datetime_array.h:586 - :ref:`View ` * - ``std::optional max() const`` - std::optional - pd_datetime_array.h:893 - :ref:`View ` * - ``std::optional min() const`` - std::optional - pd_datetime_array.h:884 - :ref:`View ` * - ``IntegerArray minute() const`` - IntegerArray - pd_datetime_array.h:982 - :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_datetime_array.h:330 - :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_datetime_array.h:810 - :ref:`View ` Combining --------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static DatetimeArray concat(const std::vector& arrays)`` - static DatetimeArray - pd_datetime_array.h:494 - :ref:`View ` Time Series ----------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeArray tz_convert(std::shared_ptr tz) const`` - DatetimeArray - pd_datetime_array.h:1449 - :ref:`View ` * - ``DatetimeArray tz_convert(const std::string& tz_name, const std::string& tz_display = "") const`` - DatetimeArray - pd_datetime_array.h:1463 - :ref:`View ` * - ``DatetimeArray tz_localize(std::shared_ptr tz, const std::string& ambiguous = "raise", const std::string& nonexistent = "raise") const`` - DatetimeArray - pd_datetime_array.h:1299 - :ref:`View ` * - ``DatetimeArray tz_localize(const std::string& tz_name, const std::string& ambiguous = "raise", const std::string& nonexistent = "raise", const std::string& tz_display = "") const`` - DatetimeArray - pd_datetime_array.h:1421 - :ref:`View ` I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::string to_string() const`` - std::string - pd_datetime_array.h:1485 - :ref:`View ` Conversion ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeArray copy() const`` - DatetimeArray - pd_datetime_array.h:433 - :ref:`View ` Set Operations -------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``DatetimeArray unique() const`` - DatetimeArray - pd_datetime_array.h:748 - :ref:`View ` Type Checking ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``BooleanArray is_leap_year() const`` - BooleanArray - pd_datetime_array.h:1208 - :ref:`View ` * - ``BooleanArray is_month_end() const`` - BooleanArray - pd_datetime_array.h:1103 - :ref:`View ` * - ``BooleanArray is_month_start() const`` - BooleanArray - pd_datetime_array.h:1084 - :ref:`View ` * - ``bool is_na(size_t index) const`` - bool - pd_datetime_array.h:404 - :ref:`View ` * - ``BooleanArray is_quarter_end() const`` - BooleanArray - pd_datetime_array.h:1146 - :ref:`View ` * - ``BooleanArray is_quarter_start() const`` - BooleanArray - pd_datetime_array.h:1125 - :ref:`View ` * - ``bool is_tz_aware() const`` - bool - pd_datetime_array.h:351 - :ref:`View ` * - ``BooleanArray is_year_end() const`` - BooleanArray - pd_datetime_array.h:1189 - :ref:`View ` * - ``BooleanArray is_year_start() const`` - BooleanArray - pd_datetime_array.h:1170 - :ref:`View ` Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::optional argmax() const`` - std::optional - pd_datetime_array.h:862 - :ref:`View ` * - ``std::optional argmin() const`` - std::optional - pd_datetime_array.h:842 - :ref:`View ` * - ``const numpy::NDArray& data() const`` - const numpy::NDArray& - pd_datetime_array.h:366 - :ref:`View ` * - ``IntegerArray day() const`` - IntegerArray - pd_datetime_array.h:944 - :ref:`View ` * - ``IntegerArray dayofweek() const`` - IntegerArray - pd_datetime_array.h:1020 - :ref:`View ` * - ``IntegerArray dayofyear() const`` - IntegerArray - pd_datetime_array.h:1041 - :ref:`View ` * - ``void detect_unit()`` - void - pd_datetime_array.h:1535 - * - ``numpy::datetime64 dt(iso_strings[i])`` - numpy::datetime64 - pd_datetime_array.h:224 - :ref:`View ` * - ``dtype_type dtype() const`` - dtype_type - pd_datetime_array.h:288 - :ref:`View ` * - ``bool empty() const`` - bool - pd_datetime_array.h:323 - :ref:`View ` * - ``std::pair, DatetimeArray> factorize() const`` - std::pair, DatetimeArray> - pd_datetime_array.h:774 - :ref:`View ` * - ``bool has_na() const`` - bool - pd_datetime_array.h:599 - :ref:`View ` * - ``IntegerArray hour() const`` - IntegerArray - pd_datetime_array.h:963 - :ref:`View ` * - ``IntegerArray month() const`` - IntegerArray - pd_datetime_array.h:925 - :ref:`View ` * - ``size_t nbytes() const`` - size_t - pd_datetime_array.h:302 - :ref:`View ` * - ``constexpr int ndim() const`` - constexpr int - pd_datetime_array.h:309 - :ref:`View ` * - ``DatetimeArray normalize() const`` - DatetimeArray - pd_datetime_array.h:1272 - :ref:`View ` * - ``IntegerArray quarter() const`` - IntegerArray - pd_datetime_array.h:1060 - :ref:`View ` * - ``std::string repr() const`` - std::string - pd_datetime_array.h:1502 - :ref:`View ` * - ``IntegerArray second() const`` - IntegerArray - pd_datetime_array.h:1001 - :ref:`View ` * - ``std::vector shape() const`` - std::vector - pd_datetime_array.h:316 - :ref:`View ` * - ``size_t size() const`` - size_t - pd_datetime_array.h:295 - :ref:`View ` * - ``store_ns(result_data, i, wall_ns)`` - - pd_datetime_array.h:1326 - * - ``store_ns(result_data, i, utc_ns)`` - - pd_datetime_array.h:1382 - * - ``store_ns(result_data, i, utc_ns)`` - - pd_datetime_array.h:1387 - * - ``store_ns(result_data, i, utc_ns)`` - - pd_datetime_array.h:1403 - * - ``store_ns(result_data, i, valid_utc_times[0])`` - - pd_datetime_array.h:1407 - * - ``store_ns(result_data, i, utc_ns)`` - - pd_datetime_array.h:1412 - * - ``std::shared_ptr tz() const`` - std::shared_ptr - pd_datetime_array.h:344 - :ref:`View ` * - ``numpy::DateTimeUnit unit() const`` - numpy::DateTimeUnit - pd_datetime_array.h:337 - :ref:`View ` * - ``void validate_arrays()`` - void - pd_datetime_array.h:1515 - * - ``IntegerArray year() const`` - IntegerArray - pd_datetime_array.h:906 - :ref:`View ` Internal Methods ---------------- *2 internal methods (prefixed with underscore)* Code Examples ------------- The following examples are extracted from the test suite. .. _example-datetimearray-from_timestamps-0: .. dropdown:: from_timestamps (pd_test_extension_array.cpp:9) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1 :emphasize-lines: 9 // pd_test_extension_array.cpp — L3 step L3.15 + Fix A storage-flip extensions // // Storage invariants and round-trip integrity for pandas::DatetimeArray and // pandas::TimedeltaArray after the Fix A storage flip // (do/plan_L3_fix_a_storage_flip.md, applied 2026-05-04). // // Verifies: // - sizeof(int64_t) == 8 (storage element size invariant) // - DatetimeArray::from_timestamps() round-trips a vector> // - NaT slots are preserved through the round-trip (mask stays consistent) // - tz-aware uniform-tz construction produces a non-null tz_ field // - Boxing reconstruction via getElementAt() recovers the input ns values // - Fix A storage shape: data() returns NDArray (8 B/elem, ns count) // - NaT sentinel: INT64_MIN round-trips through the boxing layer // - All 4 linear units (s/ms/us/ns) round-trip through ns-canonical storage // - Tz-aware boxing reconstruction (UTC, US/Eastern, +05:30) preserves tz #include "../pandas/pd_datetime_array.h" #include "../pandas/pd_timedelta_array.h" .. _example-datetimearray-at-1: .. 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-datetimearray-mask-2: .. 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-datetimearray-take-3: .. 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-datetimearray-dropna-4: .. 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-datetimearray-fillna-5: .. 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-datetimearray-isna-6: .. 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-datetimearray-notna-7: .. 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-datetimearray-count-8: .. 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-datetimearray-max-9: .. 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-datetimearray-min-10: .. 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-datetimearray-minute-11: .. dropdown:: minute (pd_test_1_all.cpp:7505) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7495 :emphasize-lines: 11 std::cout << "========= minute property ============================="; std::vector> values = { make_dt(0), // Minute 0 make_dt(30 * NS_PER_MIN), // Minute 30 make_dt(59 * NS_PER_MIN) // Minute 59 }; pandas::DatetimeArray arr(values); pandas::DatetimeIndex idx(arr); auto minutes = idx.minute(); bool passed = (minutes.size() == 3); auto m0 = minutes[0]; auto m1 = minutes[1]; auto m2 = minutes[2]; passed = passed && m0.has_value() && *m0 == 0; passed = passed && m1.has_value() && *m1 == 30; passed = passed && m2.has_value() && *m2 == 59; if (!passed) { .. _example-datetimearray-len-12: .. 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-datetimearray-argsort-13: .. 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-datetimearray-concat-14: .. 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-datetimearray-tz_convert-15: .. dropdown:: tz_convert (pd_test_2_all.cpp:17874) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 17864 :emphasize-lines: 11 std::cout << "====================================== [OK] pd_test_transform test suite ========================== " << std::endl; return 0; } } // namespace dataframe_tests // ------------------- pd_test_transform.cpp (end) ----------------------------- // ------------------- pd_test_tz_convert.cpp (start) ----------------------------- // dataframe_tests/pd_test_tz_convert.cpp // Test for DataFrame.tz_convert() method #include #include #include #include "../pandas/pd_dataframe.h" namespace dataframe_tests { namespace dataframe_tests_tz_convert { void pd_test_tz_convert_basic() { .. _example-datetimearray-tz_convert-16: .. dropdown:: tz_convert (pd_test_2_all.cpp:17874) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 17864 :emphasize-lines: 11 std::cout << "====================================== [OK] pd_test_transform test suite ========================== " << std::endl; return 0; } } // namespace dataframe_tests // ------------------- pd_test_transform.cpp (end) ----------------------------- // ------------------- pd_test_tz_convert.cpp (start) ----------------------------- // dataframe_tests/pd_test_tz_convert.cpp // Test for DataFrame.tz_convert() method #include #include #include #include "../pandas/pd_dataframe.h" namespace dataframe_tests { namespace dataframe_tests_tz_convert { void pd_test_tz_convert_basic() { .. _example-datetimearray-tz_localize-17: .. dropdown:: tz_localize (pd_test_1_all.cpp:1431) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1421 :emphasize-lines: 11 "2023-06-15" }); // Initially should be timezone-naive if (arr.is_tz_aware()) { std::cout << " [FAIL] : array should be timezone-naive initially" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: naive"); } // Localize to UTC auto localized = arr.tz_localize("UTC"); if (!localized.is_tz_aware()) { std::cout << " [FAIL] : localized array should be timezone-aware" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: localize"); } // Verify timezone name in dtype auto dt = localized.dtype(); if (!dt.is_tz_aware()) { std::cout << " [FAIL] : dtype should be timezone-aware" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: dtype tz"); .. _example-datetimearray-tz_localize-18: .. dropdown:: tz_localize (pd_test_1_all.cpp:1431) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1421 :emphasize-lines: 11 "2023-06-15" }); // Initially should be timezone-naive if (arr.is_tz_aware()) { std::cout << " [FAIL] : array should be timezone-naive initially" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: naive"); } // Localize to UTC auto localized = arr.tz_localize("UTC"); if (!localized.is_tz_aware()) { std::cout << " [FAIL] : localized array should be timezone-aware" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: localize"); } // Verify timezone name in dtype auto dt = localized.dtype(); if (!dt.is_tz_aware()) { std::cout << " [FAIL] : dtype should be timezone-aware" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: dtype tz"); .. _example-datetimearray-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-datetimearray-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-datetimearray-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-datetimearray-is_leap_year-22: .. dropdown:: is_leap_year (pd_test_1_all.cpp:1280) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1270 :emphasize-lines: 11 } // is_month_end auto me = arr.is_month_end(); if (!me[1].has_value() || !me[1].value()) { std::cout << " [FAIL] : 2023-03-31 should be month end" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end"); } // is_leap_year auto ly = arr.is_leap_year(); if (!ly[2].has_value() || !ly[2].value()) { std::cout << " [FAIL] : 2024 should be leap year" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: leap year"); } if (!ly[0].has_value() || ly[0].value()) { std::cout << " [FAIL] : 2023 should not be leap year" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not leap year"); } std::cout << " -> tests passed" << std::endl; .. _example-datetimearray-is_month_end-23: .. dropdown:: is_month_end (pd_test_1_all.cpp:1273) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1263 :emphasize-lines: 11 } // is_month_start auto ms = arr.is_month_start(); if (!ms[0].has_value() || !ms[0].value()) { std::cout << " [FAIL] : 2023-01-01 should be month start" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month start"); } // is_month_end auto me = arr.is_month_end(); if (!me[1].has_value() || !me[1].value()) { std::cout << " [FAIL] : 2023-03-31 should be month end" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end"); } // is_leap_year auto ly = arr.is_leap_year(); if (!ly[2].has_value() || !ly[2].value()) { std::cout << " [FAIL] : 2024 should be leap year" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: leap year"); .. _example-datetimearray-is_month_start-24: .. dropdown:: is_month_start (pd_test_1_all.cpp:1266) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1256 :emphasize-lines: 11 if (!ys[0].has_value() || !ys[0].value()) { std::cout << " [FAIL] : 2023-01-01 should be year start" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: year start"); } if (!ys[1].has_value() || ys[1].value()) { std::cout << " [FAIL] : 2023-03-31 should not be year start" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not year start"); } // is_month_start auto ms = arr.is_month_start(); if (!ms[0].has_value() || !ms[0].value()) { std::cout << " [FAIL] : 2023-01-01 should be month start" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month start"); } // is_month_end auto me = arr.is_month_end(); if (!me[1].has_value() || !me[1].value()) { std::cout << " [FAIL] : 2023-03-31 should be month end" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end"); .. _example-datetimearray-is_na-25: .. 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-datetimearray-is_quarter_end-26: .. dropdown:: is_quarter_end (pd_test_3_all.cpp:25056) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25046 :emphasize-lines: 11 }; pandas::Series s(dates); pandas::DatetimeProperties> dt(s); if (dt.has_nat()) throw std::runtime_error("has_nat should be false for clean series"); auto ms = dt.is_month_start(); if (ms[0] != true || ms[1] != false) throw std::runtime_error("is_month_start failed"); auto me = dt.is_month_end(); if (me[1] != true || me[0] != false) throw std::runtime_error("is_month_end failed"); auto qs = dt.is_quarter_start(); if (qs[0] != true || qs[1] != false) throw std::runtime_error("is_quarter_start failed"); auto qe = dt.is_quarter_end(); if (qe[2] != true || qe[0] != false) throw std::runtime_error("is_quarter_end failed"); auto ys = dt.is_year_start(); if (ys[0] != true || ys[1] != false) throw std::runtime_error("is_year_start failed"); auto ye = dt.is_year_end(); if (ye[3] != true || ye[0] != false) throw std::runtime_error("is_year_end failed"); std::cout << " -> tests passed" << std::endl; } void pd_test_dt_bool_na_with_nat() { std::cout << "========= pd_test_dt_bool_na: series with NaT =========="; .. _example-datetimearray-is_quarter_start-27: .. dropdown:: is_quarter_start (pd_test_3_all.cpp:25054) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25044 :emphasize-lines: 11 numpy::datetime64("2024-03-31"), numpy::datetime64("2024-12-31") }; pandas::Series s(dates); pandas::DatetimeProperties> dt(s); if (dt.has_nat()) throw std::runtime_error("has_nat should be false for clean series"); auto ms = dt.is_month_start(); if (ms[0] != true || ms[1] != false) throw std::runtime_error("is_month_start failed"); auto me = dt.is_month_end(); if (me[1] != true || me[0] != false) throw std::runtime_error("is_month_end failed"); auto qs = dt.is_quarter_start(); if (qs[0] != true || qs[1] != false) throw std::runtime_error("is_quarter_start failed"); auto qe = dt.is_quarter_end(); if (qe[2] != true || qe[0] != false) throw std::runtime_error("is_quarter_end failed"); auto ys = dt.is_year_start(); if (ys[0] != true || ys[1] != false) throw std::runtime_error("is_year_start failed"); auto ye = dt.is_year_end(); if (ye[3] != true || ye[0] != false) throw std::runtime_error("is_year_end failed"); std::cout << " -> tests passed" << std::endl; } .. _example-datetimearray-is_tz_aware-28: .. dropdown:: is_tz_aware (pd_test_1_all.cpp:1425) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1415 :emphasize-lines: 11 void pd_test_datetime_array_timezone() { std::cout << "========= DatetimeArray: timezone ======================= "; pandas::DatetimeArray arr(std::vector{ "2023-01-01", "2023-06-15" }); // Initially should be timezone-naive if (arr.is_tz_aware()) { std::cout << " [FAIL] : array should be timezone-naive initially" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: naive"); } // Localize to UTC auto localized = arr.tz_localize("UTC"); if (!localized.is_tz_aware()) { std::cout << " [FAIL] : localized array should be timezone-aware" << std::endl; throw std::runtime_error("pd_test_datetime_array_timezone failed: localize"); } .. _example-datetimearray-is_year_end-29: .. dropdown:: is_year_end (pd_test_3_all.cpp:25060) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 25050 :emphasize-lines: 11 auto ms = dt.is_month_start(); if (ms[0] != true || ms[1] != false) throw std::runtime_error("is_month_start failed"); auto me = dt.is_month_end(); if (me[1] != true || me[0] != false) throw std::runtime_error("is_month_end failed"); auto qs = dt.is_quarter_start(); if (qs[0] != true || qs[1] != false) throw std::runtime_error("is_quarter_start failed"); auto qe = dt.is_quarter_end(); if (qe[2] != true || qe[0] != false) throw std::runtime_error("is_quarter_end failed"); auto ys = dt.is_year_start(); if (ys[0] != true || ys[1] != false) throw std::runtime_error("is_year_start failed"); auto ye = dt.is_year_end(); if (ye[3] != true || ye[0] != false) throw std::runtime_error("is_year_end failed"); std::cout << " -> tests passed" << std::endl; } void pd_test_dt_bool_na_with_nat() { std::cout << "========= pd_test_dt_bool_na: series with NaT =========="; std::vector dates = { numpy::datetime64("2024-01-01"), numpy::datetime64(), // NaT numpy::datetime64("2024-12-31") .. _example-datetimearray-is_year_start-30: .. dropdown:: is_year_start (pd_test_1_all.cpp:1255) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1245 :emphasize-lines: 11 std::cout << "========= DatetimeArray: boolean properties ======================= "; pandas::DatetimeArray arr(std::vector{ "2023-01-01", // year start, month start "2023-03-31", // quarter end, month end "2024-02-29", // leap year (2024 is leap year) "2023-12-31" // year end, month end }); // is_year_start auto ys = arr.is_year_start(); if (!ys[0].has_value() || !ys[0].value()) { std::cout << " [FAIL] : 2023-01-01 should be year start" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: year start"); } if (!ys[1].has_value() || ys[1].value()) { std::cout << " [FAIL] : 2023-03-31 should not be year start" << std::endl; throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not year start"); } // is_month_start .. _example-datetimearray-argmax-31: .. 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-datetimearray-argmin-32: .. 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-datetimearray-data-33: .. 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-datetimearray-day-34: .. dropdown:: day (pd_test_1_all.cpp:1193) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1183 :emphasize-lines: 11 std::cout << " [FAIL] : month[0] should be 3" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[0]"); } auto m1 = months[1]; if (!m1.has_value() || m1.value() != 12) { std::cout << " [FAIL] : month[1] should be 12" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[1]"); } // Day auto days = arr.day(); auto d0 = days[0]; if (!d0.has_value() || d0.value() != 15) { std::cout << " [FAIL] : day[0] should be 15" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_month_day failed: day[0]"); } auto d1 = days[1]; if (!d1.has_value() || d1.value() != 25) { std::cout << " [FAIL] : day[1] should be 25" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_month_day failed: day[1]"); } .. _example-datetimearray-dayofweek-35: .. dropdown:: dayofweek (pd_test_1_all.cpp:7565) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7555 :emphasize-lines: 11 // 1970-01-01 was a Thursday (day 3) std::vector> values = { make_dt(0), // Thursday (3) make_dt(NS_PER_DAY), // Friday (4) make_dt(2 * NS_PER_DAY), // Saturday (5) make_dt(3 * NS_PER_DAY) // Sunday (6) }; pandas::DatetimeArray arr(values); pandas::DatetimeIndex idx(arr); auto dow = idx.dayofweek(); bool passed = (dow.size() == 4); if (!passed) { std::cout << " [FAIL] : in pd_test_datetime_index_dayofweek()" << std::endl; throw std::runtime_error("pd_test_datetime_index_dayofweek failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-datetimearray-dayofyear-36: .. dropdown:: dayofyear (pd_test_3_all.cpp:18582) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18572 :emphasize-lines: 11 auto seconds = s.dt().second(); if (seconds[0] != 45 || seconds[1] != 30 || seconds[2] != 59) { std::cout << " [FAIL] : second() failed" << std::endl; throw std::runtime_error("pd_test_dt_time_components: second() failed"); } std::cout << " -> tests passed" << std::endl; } // ============================================================================ // Test dt().dayofweek(), dt().dayofyear(), dt().quarter() // ============================================================================ void pd_test_dt_derived_properties() { std::cout << "========= Series.dt().dayofweek/dayofyear/quarter() ======"; // 2020-01-01 is a Wednesday (dayofweek=2), dayofyear=1, Q1 // 2020-07-04 is a Saturday (dayofweek=5), dayofyear=186, Q3 pandas::Series s({"2020-01-01", "2020-07-04"}); auto dow = s.dt().dayofweek(); .. _example-datetimearray-dt-37: .. dropdown:: dt (pd_test_3_all.cpp:18239) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18229 :emphasize-lines: 11 if (offset.freqstr() != "D") { std::cout << " [FAIL] : Day freqstr() failed" << std::endl; throw std::runtime_error("pd_test_day_offset: freqstr() failed"); } if (offset.name() != "Day") { std::cout << " [FAIL] : Day name() failed" << std::endl; throw std::runtime_error("pd_test_day_offset: name() failed"); } // Test apply numpy::datetime64 dt("2020-01-15"); auto result = offset.apply(dt); std::tm tm = result.toTm(); if (tm.tm_mday != 20) { std::cout << " [FAIL] : Day apply() failed, got day " << tm.tm_mday << std::endl; throw std::runtime_error("pd_test_day_offset: apply() failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-datetimearray-dtype-38: .. 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-datetimearray-empty-39: .. 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-datetimearray-factorize-40: .. 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-datetimearray-has_na-41: .. 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-datetimearray-hour-42: .. dropdown:: hour (pd_test_1_all.cpp:7476) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7466 :emphasize-lines: 11 std::cout << "========= hour property ==============================="; std::vector> values = { make_dt(0), // Hour 0 make_dt(6 * NS_PER_HOUR), // Hour 6 make_dt(23 * NS_PER_HOUR) // Hour 23 }; pandas::DatetimeArray arr(values); pandas::DatetimeIndex idx(arr); auto hours = idx.hour(); bool passed = (hours.size() == 3); auto h0 = hours[0]; auto h1 = hours[1]; auto h2 = hours[2]; passed = passed && h0.has_value() && *h0 == 0; passed = passed && h1.has_value() && *h1 == 6; passed = passed && h2.has_value() && *h2 == 23; if (!passed) { .. _example-datetimearray-month-43: .. dropdown:: month (pd_test_1_all.cpp:1180) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1170 :emphasize-lines: 11 void pd_test_datetime_array_component_month_day() { std::cout << "========= DatetimeArray: month/day components ======================= "; pandas::DatetimeArray arr(std::vector{ "2023-03-15", "2023-12-25", "NaT" }); // Month auto months = arr.month(); auto m0 = months[0]; if (!m0.has_value() || m0.value() != 3) { std::cout << " [FAIL] : month[0] should be 3" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[0]"); } auto m1 = months[1]; if (!m1.has_value() || m1.value() != 12) { std::cout << " [FAIL] : month[1] should be 12" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[1]"); } .. _example-datetimearray-nbytes-44: .. 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-datetimearray-ndim-45: .. 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-datetimearray-normalize-46: .. dropdown:: normalize (pd_test_1_all.cpp:8723) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 8713 :emphasize-lines: 11 void pd_test_datetime_mixin_normalize() { std::cout << "========= normalize ==================================="; // Create datetime with time component std::vector> values = { numpy::datetime64(86400000000000LL + 3600000000000LL, numpy::DateTimeUnit::Nanosecond) // 1 day + 1 hour }; pandas::DatetimeArray arr(values); pandas::DatetimeMixinIndex idx(arr); pandas::DatetimeMixinIndex normalized = idx.normalize(); bool passed = (normalized.size() == 1); if (!passed) { std::cout << " [FAIL] : in pd_test_datetime_mixin_normalize()" << std::endl; throw std::runtime_error("pd_test_datetime_mixin_normalize failed"); } std::cout << " -> tests passed" << std::endl; } .. _example-datetimearray-quarter-47: .. dropdown:: quarter (pd_test_1_all.cpp:1218) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1208 :emphasize-lines: 11 void pd_test_datetime_array_quarter() { std::cout << "========= DatetimeArray: quarter ======================= "; pandas::DatetimeArray arr(std::vector{ "2023-01-15", // Q1 "2023-05-20", // Q2 "2023-09-10", // Q3 "2023-11-25" // Q4 }); auto quarters = arr.quarter(); auto q0 = quarters[0]; if (!q0.has_value() || q0.value() != 1) { std::cout << " [FAIL] : quarter[0] should be 1" << std::endl; throw std::runtime_error("pd_test_datetime_array_quarter failed: quarter[0]"); } auto q1 = quarters[1]; if (!q1.has_value() || q1.value() != 2) { std::cout << " [FAIL] : quarter[1] should be 2" << std::endl; throw std::runtime_error("pd_test_datetime_array_quarter failed: quarter[1]"); .. _example-datetimearray-repr-48: .. 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-datetimearray-second-49: .. dropdown:: second (pd_test_1_all.cpp:7534) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7524 :emphasize-lines: 11 std::cout << "========= second property ============================="; std::vector> values = { make_dt(0), // Second 0 make_dt(30 * NS_PER_SEC), // Second 30 make_dt(59 * NS_PER_SEC) // Second 59 }; pandas::DatetimeArray arr(values); pandas::DatetimeIndex idx(arr); auto seconds = idx.second(); bool passed = (seconds.size() == 3); auto s0 = seconds[0]; auto s1 = seconds[1]; auto s2 = seconds[2]; passed = passed && s0.has_value() && *s0 == 0; passed = passed && s1.has_value() && *s1 == 30; passed = passed && s2.has_value() && *s2 == 59; if (!passed) { .. _example-datetimearray-shape-50: .. 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-datetimearray-size-51: .. 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-datetimearray-tz-52: .. dropdown:: tz (pd_test_2_all.cpp:17914) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 17904 :emphasize-lines: 11 pandas::DataFrame df(data); df.set_index(std::make_unique(tz_aware_idx)); // Verify the index is timezone-aware const pandas::DatetimeIndex* original_idx = dynamic_cast(&df.index()); if (!original_idx) { std::cout << " [FAIL] : in pd_test_tz_convert_basic() : index is not DatetimeIndex" << std::endl; throw std::runtime_error("pd_test_tz_convert_basic failed: index is not DatetimeIndex"); } std::string original_tz = original_idx->tz(); if (original_tz.empty()) { std::cout << " [FAIL] : in pd_test_tz_convert_basic() : original index is not timezone-aware" << std::endl; throw std::runtime_error("pd_test_tz_convert_basic failed: original index is not timezone-aware"); } // Convert to Asia/Shanghai timezone pandas::DataFrame df_shanghai = df.tz_convert("Asia/Shanghai"); // Verify result has a DatetimeIndex const pandas::DatetimeIndex* converted_idx = dynamic_cast(&df_shanghai.index()); .. _example-datetimearray-unit-53: .. 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; } .. _example-datetimearray-year-54: .. dropdown:: year (pd_test_1_all.cpp:1147) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 1137 :emphasize-lines: 11 void pd_test_datetime_array_component_year() { std::cout << "========= DatetimeArray: year component ======================= "; pandas::DatetimeArray arr(std::vector{ "2020-01-15", "NaT", "2025-06-20" }); auto years = arr.year(); auto y0 = years[0]; if (!y0.has_value() || y0.value() != 2020) { std::cout << " [FAIL] : year[0] should be 2020" << std::endl; throw std::runtime_error("pd_test_datetime_array_component_year failed: year[0]"); } auto y1 = years[1]; if (y1.has_value()) { std::cout << " [FAIL] : year[1] should be NA (NaT)" << std::endl;