Timedelta#
-
class pandas::Timedelta#
pandas C++ class.
Example#
#include <pandas/pandas.h>
using namespace pandas;
// Use Timedelta
Timedelta obj;
// ... operations ...
Constructors#
Signature |
Location |
Example |
|---|---|---|
|
pd_timedelta.h:340 |
|
|
pd_timedelta.h:360 |
|
|
pd_timedelta.h:371 |
|
|
pd_timedelta.h:383 |
|
|
pd_timedelta.h:419 |
Construction#
Statistics#
Arithmetic#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
std::pair<int64_t, Timedelta> |
pd_timedelta.h:996 |
Combining#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
static void |
pd_timedelta.h:611 |
|
|
pd_timedelta.h:647 |
||
|
pd_timedelta.h:679 |
I/O#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
std::chrono::nanoseconds |
pd_timedelta.h:586 |
|
|
Duration |
pd_timedelta.h:595 |
|
|
int64_t |
pd_timedelta.h:579 |
|
|
numpy::timedelta64 |
pd_timedelta.h:548 |
Other Methods#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
static Timedelta |
pd_timedelta.h:428 |
|
|
Timedelta |
pd_timedelta.h:1006 |
|
|
Timedelta |
pd_timedelta.h:828 |
|
|
Timedelta |
pd_timedelta.h:775 |
|
|
int64_t |
pd_timedelta.h:512 |
|
|
std::string |
pd_timedelta.h:738 |
|
|
void |
pd_timedelta.h:69 |
|
|
int64_t |
pd_timedelta.h:469 |
|
|
int64_t |
pd_timedelta.h:464 |
|
|
Timedelta |
pd_timedelta.h:757 |
|
|
int64_t |
pd_timedelta.h:980 |
|
|
Timedelta |
pd_timedelta.h:988 |
|
|
std::string |
pd_timedelta.h:615 |
|
|
int32_t |
pd_timedelta.h:475 |
|
|
void |
pd_timedelta.h:65 |
|
|
bool |
pd_timedelta.h:450 |
|
|
std::string |
pd_timedelta.h:687 |
|
|
int32_t |
pd_timedelta.h:499 |
|
|
int32_t |
pd_timedelta.h:493 |
|
|
int32_t |
pd_timedelta.h:505 |
|
|
static int64_t |
pd_timedelta.h:165 |
|
|
static int64_t |
pd_timedelta.h:103 |
|
|
static int64_t |
pd_timedelta.h:116 |
|
|
static Timedelta |
pd_timedelta.h:442 |
|
|
Timedelta |
pd_timedelta.h:796 |
|
|
std::string |
pd_timedelta.h:717 |
|
|
int32_t |
pd_timedelta.h:487 |
|
|
std::istringstream |
pd_timedelta.h:237 |
|
|
std::string |
pd_timedelta.h:626 |
|
|
double |
pd_timedelta.h:533 |
|
|
double |
pd_timedelta.h:528 |
|
|
double |
pd_timedelta.h:523 |
|
|
double |
pd_timedelta.h:538 |
|
|
double |
pd_timedelta.h:518 |
|
|
int64_t |
pd_timedelta.h:459 |
Code Examples#
The following examples are extracted from the test suite.
Timedelta (pd_test_5_all.cpp:25576)
25566 apply_default_display(df);
25567 check_str("case_38.datetime_with_nat_site4",
25568 EXPECTED_case_38_datetime_with_nat_site4,
25569 df.to_string(), local_fail);
25570}
25571
25572void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) {
25573 std::cout << "----- case_39_timedelta_site3 -----\n";
25574 pandas::DataFrame df;
25575 std::vector<pandas::Timedelta> tds = {
25576 pandas::Timedelta("1 days"),
25577 pandas::Timedelta("2 days"),
25578 pandas::Timedelta("-1 days"),
25579 pandas::Timedelta("3 days"),
25580 };
25581 df.add_column<pandas::Timedelta>("td", tds);
25582 df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"});
25583 df.set_multiindex(make_mi_ab_short());
25584 apply_default_display(df);
25585 check_str("case_39.timedelta_site3",
25586 EXPECTED_case_39_timedelta_site3,
Timedelta (pd_test_5_all.cpp:25576)
25566 apply_default_display(df);
25567 check_str("case_38.datetime_with_nat_site4",
25568 EXPECTED_case_38_datetime_with_nat_site4,
25569 df.to_string(), local_fail);
25570}
25571
25572void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) {
25573 std::cout << "----- case_39_timedelta_site3 -----\n";
25574 pandas::DataFrame df;
25575 std::vector<pandas::Timedelta> tds = {
25576 pandas::Timedelta("1 days"),
25577 pandas::Timedelta("2 days"),
25578 pandas::Timedelta("-1 days"),
25579 pandas::Timedelta("3 days"),
25580 };
25581 df.add_column<pandas::Timedelta>("td", tds);
25582 df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"});
25583 df.set_multiindex(make_mi_ab_short());
25584 apply_default_display(df);
25585 check_str("case_39.timedelta_site3",
25586 EXPECTED_case_39_timedelta_site3,
Timedelta (pd_test_5_all.cpp:25576)
25566 apply_default_display(df);
25567 check_str("case_38.datetime_with_nat_site4",
25568 EXPECTED_case_38_datetime_with_nat_site4,
25569 df.to_string(), local_fail);
25570}
25571
25572void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) {
25573 std::cout << "----- case_39_timedelta_site3 -----\n";
25574 pandas::DataFrame df;
25575 std::vector<pandas::Timedelta> tds = {
25576 pandas::Timedelta("1 days"),
25577 pandas::Timedelta("2 days"),
25578 pandas::Timedelta("-1 days"),
25579 pandas::Timedelta("3 days"),
25580 };
25581 df.add_column<pandas::Timedelta>("td", tds);
25582 df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"});
25583 df.set_multiindex(make_mi_ab_short());
25584 apply_default_display(df);
25585 check_str("case_39.timedelta_site3",
25586 EXPECTED_case_39_timedelta_site3,
Timedelta (pd_test_5_all.cpp:25576)
25566 apply_default_display(df);
25567 check_str("case_38.datetime_with_nat_site4",
25568 EXPECTED_case_38_datetime_with_nat_site4,
25569 df.to_string(), local_fail);
25570}
25571
25572void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) {
25573 std::cout << "----- case_39_timedelta_site3 -----\n";
25574 pandas::DataFrame df;
25575 std::vector<pandas::Timedelta> tds = {
25576 pandas::Timedelta("1 days"),
25577 pandas::Timedelta("2 days"),
25578 pandas::Timedelta("-1 days"),
25579 pandas::Timedelta("3 days"),
25580 };
25581 df.add_column<pandas::Timedelta>("td", tds);
25582 df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"});
25583 df.set_multiindex(make_mi_ab_short());
25584 apply_default_display(df);
25585 check_str("case_39.timedelta_site3",
25586 EXPECTED_case_39_timedelta_site3,
Timedelta (pd_test_5_all.cpp:25576)
25566 apply_default_display(df);
25567 check_str("case_38.datetime_with_nat_site4",
25568 EXPECTED_case_38_datetime_with_nat_site4,
25569 df.to_string(), local_fail);
25570}
25571
25572void f_set_index_col_multiindex_display_10_507319_case_39_timedelta_site3(int& local_fail) {
25573 std::cout << "----- case_39_timedelta_site3 -----\n";
25574 pandas::DataFrame df;
25575 std::vector<pandas::Timedelta> tds = {
25576 pandas::Timedelta("1 days"),
25577 pandas::Timedelta("2 days"),
25578 pandas::Timedelta("-1 days"),
25579 pandas::Timedelta("3 days"),
25580 };
25581 df.add_column<pandas::Timedelta>("td", tds);
25582 df.set_columns_levels({{"G"}, {"td"}}, {"top", "leaf"});
25583 df.set_multiindex(make_mi_ab_short());
25584 apply_default_display(df);
25585 check_str("case_39.timedelta_site3",
25586 EXPECTED_case_39_timedelta_site3,
from_string (pd_test_3_all.cpp:10837)
10827 const auto& s1 = df.column<int64_t>("A");
10828 const auto& s2 = df.col<int64_t>("A");
10829 if (s1.size() != s2.size() || s1[0] != s2[0]) {
10830 std::cout << " [FAIL] : in pd_test_3_all_column_alias() : mismatch" << std::endl;
10831 throw std::runtime_error("pd_test_3_all_column_alias failed");
10832 }
10833 std::cout << " -> tests passed" << std::endl;
10834}
10835
10836void pd_test_3_all_timedelta_from_string() {
10837 std::cout << "========= Timedelta::from_string() ======================";
10838 auto td1 = pandas::Timedelta::from_string("1 days");
10839 pandas::Timedelta td2("1 days");
10840 if (td1.value() != td2.value()) {
10841 std::cout << " [FAIL] : in pd_test_3_all_timedelta_from_string() : mismatch" << std::endl;
10842 throw std::runtime_error("pd_test_3_all_timedelta_from_string failed");
10843 }
10844 std::cout << " -> tests passed" << std::endl;
10845}
10846
10847void pd_test_3_all_replace_int() {
from_value (pd_test_timedelta_scalar.cpp:158)
148 std::cout << " Timedelta(2, 'W') = " << td_week.days() << " days" << std::endl;
149 if (td_week.days() != 14) {
150 std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(2, 'W') expected 14 days, got "
151 << td_week.days() << std::endl;
152 errors++;
153 }
154 }
155
156 // From value and unit - static factory for fractional values
157 {
158 pandas::Timedelta td_frac = pandas::Timedelta::from_value(1.5, "h"); // 1.5 hours = 90 minutes
159 std::cout << " Timedelta::from_value(1.5, 'h') = " << td_frac.total_minutes() << " minutes" << std::endl;
160 if (std::abs(td_frac.total_minutes() - 90.0) > 0.0001) {
161 std::cout << "[FAIL] np_test_timedelta_constructors: from_value(1.5, 'h') expected 90 minutes, got "
162 << td_frac.total_minutes() << std::endl;
163 errors++;
164 }
165
166 pandas::Timedelta td_frac2 = pandas::Timedelta::from_value(0.5, "D"); // 0.5 days = 12 hours
167 std::cout << " Timedelta::from_value(0.5, 'D') = " << td_frac2.total_hours() << " hours" << std::endl;
168 if (std::abs(td_frac2.total_hours() - 12.0) > 0.0001) {
max (pd_test_1_all.cpp:771)
761 pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats, true); // ordered
762
763 // Test min
764 std::optional<std::string> min_val = arr.min();
765 if (!min_val.has_value() || *min_val != "low") {
766 std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : min != 'low'" << std::endl;
767 throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: min != 'low'");
768 }
769
770 // Test max
771 std::optional<std::string> max_val = arr.max();
772 if (!max_val.has_value() || *max_val != "high") {
773 std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : max != 'high'" << std::endl;
774 throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: max != 'high'");
775 }
776
777 // Test unordered throws for min/max
778 pandas::CategoricalArray unordered = arr.as_unordered();
779 bool threw = false;
780 try {
781 unordered.min();
min (pd_test_1_all.cpp:764)
754 }
755
756 void pd_test_categorical_array_ordered_operations() {
757 std::cout << "========= CategoricalArray: ordered operations (min/max) ======================= ";
758
759 std::vector<std::string> cats = {"low", "medium", "high"};
760 std::vector<numpy::int32> codes = {0, 2, 1, 0, -1}; // low, high, medium, low, NA
761 pandas::CategoricalArray arr = pandas::CategoricalArray::from_codes(codes, cats, true); // ordered
762
763 // Test min
764 std::optional<std::string> min_val = arr.min();
765 if (!min_val.has_value() || *min_val != "low") {
766 std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : min != 'low'" << std::endl;
767 throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: min != 'low'");
768 }
769
770 // Test max
771 std::optional<std::string> max_val = arr.max();
772 if (!max_val.has_value() || *max_val != "high") {
773 std::cout << " [FAIL] : in pd_test_categorical_array_ordered_operations() : max != 'high'" << std::endl;
774 throw std::runtime_error("pd_test_categorical_array_ordered_operations failed: max != 'high'");
minutes (pd_test_3_all.cpp:21614)
21604 }
21605 if (d.months() != 2) {
21606 throw std::runtime_error("DateOffset: months mismatch");
21607 }
21608 if (d.days() != 5) {
21609 throw std::runtime_error("DateOffset: days mismatch");
21610 }
21611 if (d.hours() != 3) {
21612 throw std::runtime_error("DateOffset: hours mismatch");
21613 }
21614 if (d.minutes() != 30) {
21615 throw std::runtime_error("DateOffset: minutes mismatch");
21616 }
21617 if (d.seconds() != 10) {
21618 throw std::runtime_error("DateOffset: seconds mismatch");
21619 }
21620
21621 std::cout << " -> tests passed" << std::endl;
21622}
21623
21624void test_yearend_freqstr() {
divmod (pd_test_3_all.cpp:12077)
12067 auto cov_val = s1.cov(s2);
12068 if (!cov_val.has_value()) {
12069 std::cout << " [FAIL] : covariance should have a value" << std::endl;
12070 throw std::runtime_error("pd_test_series_corr_cov failed");
12071 }
12072
12073 std::cout << " -> tests passed" << std::endl;
12074}
12075
12076// ============================================================================
12077// Test 9: divmod()
12078// ============================================================================
12079void pd_test_series_divmod() {
12080 std::cout << "========= Series.divmod() ==========================";
12081
12082 std::vector<double> vals = {10.0, 20.0, 30.0};
12083 pandas::Series<double> s(vals, "test");
12084
12085 auto [quot, rem] = s.divmod(7.0);
12086
12087 // 10/7 = 1 remainder 3
to_chrono (pd_test_timedelta_scalar.cpp:400)
390 int64_t nanos = td.to_numpy();
391 if (nanos != pandas::Timedelta::NANOS_PER_DAY) {
392 std::cout << "[FAIL] np_test_timedelta_conversions: to_numpy expected "
393 << pandas::Timedelta::NANOS_PER_DAY << ", got " << nanos << std::endl;
394 errors++;
395 }
396 }
397
398 // to_chrono
399 {
400 std::chrono::nanoseconds dur = td.to_chrono();
401 if (dur.count() != pandas::Timedelta::NANOS_PER_DAY) {
402 std::cout << "[FAIL] np_test_timedelta_conversions: to_chrono expected "
403 << pandas::Timedelta::NANOS_PER_DAY << ", got " << dur.count() << std::endl;
404 errors++;
405 }
406 }
407
408 // to_chrono_duration
409 {
410 auto hrs = td.to_chrono_duration<std::chrono::hours>();
to_chrono_duration (pd_test_timedelta_scalar.cpp:410)
400 std::chrono::nanoseconds dur = td.to_chrono();
401 if (dur.count() != pandas::Timedelta::NANOS_PER_DAY) {
402 std::cout << "[FAIL] np_test_timedelta_conversions: to_chrono expected "
403 << pandas::Timedelta::NANOS_PER_DAY << ", got " << dur.count() << std::endl;
404 errors++;
405 }
406 }
407
408 // to_chrono_duration
409 {
410 auto hrs = td.to_chrono_duration<std::chrono::hours>();
411 if (hrs.count() != 24) {
412 std::cout << "[FAIL] np_test_timedelta_conversions: to_chrono_duration<hours> expected 24, got "
413 << hrs.count() << std::endl;
414 errors++;
415 }
416 }
417
418 if (errors == 0) {
419 std::cout << "np_test_timedelta_conversions -> tests passed" << std::endl;
420 }
to_numpy (pd_test_1_all.cpp:16764)
16754 // =====================================================================
16755 // to_numpy Tests
16756 // =====================================================================
16757
16758 void pd_test_ndframe_to_numpy() {
16759 std::cout << "========= to_numpy =============================================" << std::endl;
16760
16761 pandas::Series<int> s({10, 20, 30});
16762
16763 auto arr = s.to_numpy();
16764
16765 bool passed = arr.getSize() == 3;
16766 if (!passed) {
16767 std::cout << " [FAIL] : in pd_test_ndframe_to_numpy() : size" << std::endl;
16768 throw std::runtime_error("pd_test_ndframe_to_numpy failed: size");
16769 }
16770
16771 passed = arr.getElementAt({0}) == 10 && arr.getElementAt({1}) == 20 && arr.getElementAt({2}) == 30;
16772 if (!passed) {
16773 std::cout << " [FAIL] : in pd_test_ndframe_to_numpy() : values" << std::endl;
to_timedelta64 (pd_test_timedelta_scalar.cpp:370)
360// =============================================================================
361// Test 5: Conversion Methods
362// =============================================================================
363int np_test_timedelta_conversions() {
364 int errors = 0;
365
366 pandas::Timedelta td(1, 0, 0); // 1 day
367
368 // to_timedelta64 with Day unit
369 {
370 numpy::timedelta64 td64 = td.to_timedelta64(numpy::DateTimeUnit::Day);
371 if (td64.getValue() != 1) {
372 std::cout << "[FAIL] np_test_timedelta_conversions: to_timedelta64(Day) expected 1, got "
373 << td64.getValue() << std::endl;
374 errors++;
375 }
376 }
377
378 // to_timedelta64 with Hour unit
379 {
380 numpy::timedelta64 td64 = td.to_timedelta64(numpy::DateTimeUnit::Hour);
NaT (pd_test_1_all.cpp:1305)
1295 pandas::DatetimeArray arr(std::vector<std::string>{
1296 "2023-06-15",
1297 "NaT",
1298 "2023-01-01",
1299 "2023-12-31"
1300 });
1301
1302 // argsort ascending
1303 auto indices = arr.argsort(true, "last");
1304 // Expected order: 2023-01-01(2), 2023-06-15(0), 2023-12-31(3), NaT(1)
1305 if (indices.getElementAt({0}) != 2) {
1306 std::cout << " [FAIL] : argsort: first should be index 2 (2023-01-01)" << std::endl;
1307 throw std::runtime_error("pd_test_datetime_array_sorting failed: argsort first");
1308 }
1309 if (indices.getElementAt({3}) != 1) {
1310 std::cout << " [FAIL] : argsort: last should be index 1 (NaT)" << std::endl;
1311 throw std::runtime_error("pd_test_datetime_array_sorting failed: NaT position");
1312 }
1313
1314 // argmin
abs (pd_test_1_all.cpp:283)
273 std::optional<bool>(true)
274 });
275
276 auto s = arr.sum();
277 if (!s.has_value() || s.value() != 3) {
278 std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : sum should be 3" << std::endl;
279 throw std::runtime_error("pd_test_boolean_array_reductions failed: sum");
280 }
281
282 auto m = arr.mean();
283 if (!m.has_value() || std::abs(m.value() - 0.75) > 0.001) {
284 std::cout << " [FAIL] : in pd_test_boolean_array_reductions() : mean should be 0.75" << std::endl;
285 throw std::runtime_error("pd_test_boolean_array_reductions failed: mean");
286 }
287
288 std::cout << " -> tests passed" << std::endl;
289 }
290
291 void pd_test_boolean_array_dtype() {
292 std::cout << "========= BooleanArray: dtype ======================= ";
as_unit (pd_test_1_all.cpp:9361)
9351 data.setElementAt({1}, numpy::datetime64(2000000000LL, numpy::DateTimeUnit::Nanosecond)); // 2 seconds in ns
9352
9353 numpy::NDArray<numpy::bool_> mask(std::vector<size_t>{2});
9354 mask.setElementAt({0}, numpy::bool_(false));
9355 mask.setElementAt({1}, numpy::bool_(false));
9356
9357 pandas::DatetimeArray arr(data, mask);
9358 pandas::DatetimeTDMixin idx(arr, "test");
9359
9360 // Convert to microseconds
9361 pandas::DatetimeTDMixin us_idx = idx.as_unit("us");
9362
9363 // Convert to same unit (should return identical)
9364 pandas::DatetimeTDMixin same_idx = idx.as_unit("ns");
9365
9366 bool passed = (us_idx.size() == 2 && same_idx.size() == 2 &&
9367 us_idx.name().has_value() && *us_idx.name() == "test");
9368 if (!passed) {
9369 std::cout << " [FAIL] : in pd_test_datetime_as_unit() : as_unit check failed" << std::endl;
9370 throw std::runtime_error("pd_test_datetime_as_unit failed");
9371 }
ceil (pd_test_1_all.cpp:4949)
4939 throw std::runtime_error("pd_test_arithmetic_series_round failed: round failed");
4940 }
4941
4942 auto f = a.floor();
4943 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;
4944 if (!passed) {
4945 std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : floor failed" << std::endl;
4946 throw std::runtime_error("pd_test_arithmetic_series_round failed: floor failed");
4947 }
4948
4949 auto c = a.ceil();
4950 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;
4951 if (!passed) {
4952 std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : ceil failed" << std::endl;
4953 throw std::runtime_error("pd_test_arithmetic_series_round failed: ceil failed");
4954 }
4955
4956 // Round with decimals
4957 pandas::Series<double> b({1.234, 2.567, 3.891});
4958 auto r2 = b.round(2);
4959 passed = std::abs(r2[0] - 1.23) < 0.001 && std::abs(r2[1] - 2.57) < 0.001;
components_days (pd_test_timedelta_scalar.cpp:282)
272 if (td.nanoseconds() != 300) {
273 std::cout << "[FAIL] np_test_timedelta_components: nanoseconds() expected 300, got "
274 << td.nanoseconds() << std::endl;
275 errors++;
276 }
277 }
278
279 // Components alias
280 {
281 pandas::Timedelta td(5, 0, 0);
282 if (td.components_days() != 5) {
283 std::cout << "[FAIL] np_test_timedelta_components: components_days() expected 5, got "
284 << td.components_days() << std::endl;
285 errors++;
286 }
287 }
288
289 if (errors == 0) {
290 std::cout << "np_test_timedelta_components -> tests passed" << std::endl;
291 }
292 return errors;
components_str (pd_test_timedelta_scalar.cpp:476)
466 if (iso.find("P1D") == std::string::npos) {
467 std::cout << "[FAIL] np_test_timedelta_strings: isoformat expected 'P1D...', got '"
468 << iso << "'" << std::endl;
469 errors++;
470 }
471 }
472
473 // components_str
474 {
475 pandas::Timedelta td(1, 2, 30, 45, 100, 200, 300);
476 std::string comp = td.components_str();
477 if (comp.find("days=1") == std::string::npos) {
478 std::cout << "[FAIL] np_test_timedelta_strings: components_str missing days=1, got '"
479 << comp << "'" << std::endl;
480 errors++;
481 }
482 }
483
484 if (errors == 0) {
485 std::cout << "np_test_timedelta_strings -> tests passed" << std::endl;
486 }
days (pd_test_1_all.cpp:4160)
4150 void pd_test_timedelta_array_component_days() {
4151 std::cout << "========= TimedeltaArray: days component ======================= ";
4152
4153 pandas::TimedeltaArray arr({
4154 std::optional<numpy::timedelta64>(numpy::timedelta64(3, numpy::DateTimeUnit::Day)),
4155 std::nullopt,
4156 std::optional<numpy::timedelta64>(numpy::timedelta64(36, numpy::DateTimeUnit::Hour)) // 1.5 days
4157 });
4158
4159 auto days_arr = arr.days();
4160
4161 auto d0 = days_arr[0];
4162 if (!d0.has_value() || d0.value() != 3) {
4163 std::cout << " [FAIL] : days[0] should be 3" << std::endl;
4164 throw std::runtime_error("pd_test_timedelta_array_component_days failed: days[0]");
4165 }
4166
4167 auto d1 = days_arr[1];
4168 if (d1.has_value()) {
4169 std::cout << " [FAIL] : days[1] should be NA (NaT)" << std::endl;
delta (pd_test_timedelta_scalar.cpp:345)
335 // total_days
336 {
337 double days = td.total_days();
338 if (std::abs(days - 1.5) > 0.0001) {
339 std::cout << "[FAIL] np_test_timedelta_total_conversions: total_days expected 1.5, got "
340 << days << std::endl;
341 errors++;
342 }
343 }
344
345 // value() and delta()
346 {
347 if (td.value() != td.delta()) {
348 std::cout << "[FAIL] np_test_timedelta_total_conversions: value() != delta()"
349 << std::endl;
350 errors++;
351 }
352 }
353
354 if (errors == 0) {
355 std::cout << "np_test_timedelta_total_conversions -> tests passed" << std::endl;
floor (pd_test_1_all.cpp:4942)
4932 pandas::Series<double> a({1.4, 2.5, 3.6, -1.4, -2.5});
4933
4934 auto r = a.round();
4935 bool passed = std::abs(r[0] - 1.0) < 0.001 && std::abs(r[2] - 4.0) < 0.001;
4936 if (!passed) {
4937 std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : round failed" << std::endl;
4938 throw std::runtime_error("pd_test_arithmetic_series_round failed: round failed");
4939 }
4940
4941 auto f = a.floor();
4942 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;
4943 if (!passed) {
4944 std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : floor failed" << std::endl;
4945 throw std::runtime_error("pd_test_arithmetic_series_round failed: floor failed");
4946 }
4947
4948 auto c = a.ceil();
4949 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;
4950 if (!passed) {
4951 std::cout << " [FAIL] : in pd_test_arithmetic_series_round() : ceil failed" << std::endl;
hours (pd_test_1_all.cpp:9567)
9557 std::cout << std::endl << " [FAIL] : floor result incorrect";
9558 passed = false;
9559 }
9560
9561 // ceil should give 2 hours
9562 if (ceiled.total_seconds() != 7200.0) {
9563 std::cout << std::endl << " [FAIL] : ceil result incorrect";
9564 passed = false;
9565 }
9566
9567 // round should give 2 hours (30m45s > 30m)
9568 if (rounded.total_seconds() != 7200.0) {
9569 std::cout << std::endl << " [FAIL] : round result incorrect";
9570 passed = false;
9571 }
9572
9573 if (!passed) {
9574 throw std::runtime_error("pd_test_timedelta_rounding_params failed");
9575 }
9576
9577 std::cout << " -> tests passed" << std::endl;
isNaT (pd_test_3_all.cpp:1523)
1513 }
1514
1515 // Case B: pandas::Timedelta == pandas::Timedelta
1516 {
1517 static_assert(std::is_same_v<pandas::Timedelta, pandas::Timedelta>,
1518 "pandas::Timedelta must alias pandas::Timedelta");
1519 }
1520
1521 // Case C: pandas::NaT is a NaT-valued Timestamp
1522 {
1523 if (!pandas::NaT.isNaT()) {
1524 throw std::runtime_error("pandas::NaT is not a NaT value");
1525 }
1526 pandas::Timestamp default_ts;
1527 if (default_ts.isNaT() != pandas::NaT.isNaT()) {
1528 throw std::runtime_error(
1529 "pandas::NaT and default Timestamp NaT-state mismatch");
1530 }
1531 }
1532
1533 // Case D: round-trip - reproduces the failing test pattern
isoformat (pd_test_timedelta_scalar.cpp:465)
455 if (nat.toString() != "NaT") {
456 std::cout << "[FAIL] np_test_timedelta_strings: toString(NaT) expected 'NaT', got '"
457 << nat.toString() << "'" << std::endl;
458 errors++;
459 }
460 }
461
462 // isoformat
463 {
464 pandas::Timedelta td(1, 2, 30);
465 std::string iso = td.isoformat();
466 if (iso.find("P1D") == std::string::npos) {
467 std::cout << "[FAIL] np_test_timedelta_strings: isoformat expected 'P1D...', got '"
468 << iso << "'" << std::endl;
469 errors++;
470 }
471 }
472
473 // components_str
474 {
475 pandas::Timedelta td(1, 2, 30, 45, 100, 200, 300);
microseconds (pd_test_1_all.cpp:19701)
19691 constexpr int64_t NS_PER_US = 1000LL;
19692 std::vector<std::optional<numpy::timedelta64>> values = {
19693 make_td(0), // 0 us
19694 make_td(500 * NS_PER_US), // 500 us
19695 make_td(NS_PER_SEC + 100 * NS_PER_US) // 1 sec + 100 us
19696 };
19697 pandas::TimedeltaArray arr(values);
19698 pandas::TimedeltaIndex idx(arr);
19699
19700 auto microseconds = idx.microseconds();
19701
19702 bool passed = (microseconds.size() == 3);
19703 if (!passed) {
19704 std::cout << " [FAIL] : in pd_test_timedelta_index_microseconds()" << std::endl;
19705 throw std::runtime_error("pd_test_timedelta_index_microseconds failed");
19706 }
19707
19708 std::cout << " -> tests passed" << std::endl;
19709}
milliseconds (pd_test_2_all.cpp:10201)
10191#include <Windows.h>
10192#endif
10193
10194namespace dataframe_tests {
10195 namespace dataframe_tests_to_clipboard {
10196
10197 // Helper function to get clipboard content (Windows only)
10198#ifdef _WIN32
10199 std::string get_clipboard_text() {
10200 // Add small delay to allow clipboard to stabilize
10201 std::this_thread::sleep_for(std::chrono::milliseconds(5));
10202
10203 if (!OpenClipboard(nullptr)) {
10204 return "";
10205 }
10206
10207 HANDLE hData = GetClipboardData(CF_TEXT);
10208 if (hData == nullptr) {
10209 CloseClipboard();
10210 return "";
10211 }
nanoseconds (pd_test_1_all.cpp:9379)
9369 std::cout << " [FAIL] : in pd_test_datetime_as_unit() : as_unit check failed" << std::endl;
9370 throw std::runtime_error("pd_test_datetime_as_unit failed");
9371 }
9372
9373 std::cout << " -> tests passed" << std::endl;
9374}
9375
9376void pd_test_timedelta_as_unit() {
9377 std::cout << "========= TimedeltaTDMixin as_unit =========================";
9378
9379 // Create index in nanoseconds (1 hour, 2 hours)
9380 numpy::NDArray<numpy::timedelta64> data(std::vector<size_t>{2});
9381 data.setElementAt({0}, numpy::timedelta64(3600000000000LL, numpy::DateTimeUnit::Nanosecond)); // 1 hour
9382 data.setElementAt({1}, numpy::timedelta64(7200000000000LL, numpy::DateTimeUnit::Nanosecond)); // 2 hours
9383
9384 numpy::NDArray<numpy::bool_> mask(std::vector<size_t>{2});
9385 mask.setElementAt({0}, numpy::bool_(false));
9386 mask.setElementAt({1}, numpy::bool_(false));
9387
9388 pandas::TimedeltaArray arr(data, mask);
9389 pandas::TimedeltaTDMixin idx(arr, "durations");
resolution (pd_test_1_all.cpp:15536)
15526 }
15527
15528 std::cout << " -> tests passed" << std::endl;
15529}
15530
15531// ============================================================================
15532// Resolution Tests
15533// ============================================================================
15534
15535void pd_test_datetime_index_resolution() {
15536 std::cout << "========= DatetimeIndex resolution() =========================";
15537
15538 numpy::NDArray<numpy::datetime64> data(std::vector<size_t>{1});
15539 data.setElementAt({0}, numpy::datetime64(1000LL, numpy::DateTimeUnit::Nanosecond));
15540
15541 numpy::NDArray<numpy::bool_> mask(std::vector<size_t>{1});
15542 mask.setElementAt({0}, numpy::bool_(false));
15543
15544 pandas::DatetimeArray arr(data, mask);
15545 pandas::DatetimeIndexBase idx(arr);
round (pd_test_1_all.cpp:1688)
1678 void pd_test_floating_array_rounding() {
1679 std::cout << "========= FloatingArray: rounding ======================= ";
1680
1681 pandas::FloatingArray<double> arr({
1682 std::optional<double>(1.234),
1683 std::optional<double>(2.567),
1684 std::nullopt
1685 });
1686
1687 auto rounded = arr.round(2);
1688 if (std::abs(rounded[0].value() - 1.23) > 0.001 ||
1689 std::abs(rounded[1].value() - 2.57) > 0.001) {
1690 std::cout << " [FAIL] : in pd_test_floating_array_rounding() : round(2)" << std::endl;
1691 throw std::runtime_error("pd_test_floating_array_rounding failed: round(2)");
1692 }
1693
1694 if (!rounded.is_na(2)) {
1695 std::cout << " [FAIL] : in pd_test_floating_array_rounding() : round should preserve NA" << std::endl;
1696 throw std::runtime_error("pd_test_floating_array_rounding failed: NA preservation");
1697 }
s_str (pd_test_5_all.cpp:83216)
83206}
83207
83208void case_7_type_mismatch_add(int& local_fail) {
83209 std::cout << "----- case_7_type_mismatch_add -----\n";
83210
83211 auto invoke = []() {
83212 // String -> "datetime64[ns, UTC]" routes through the
83213 // non-floating-point branch of astype's tz-datetime handling,
83214 // which throws pandas::TypeError via
83215 // error_messages::cannot_astype_convert (pd_series.h:7042).
83216 pandas::Series<std::string> s_str({"a", "b", "c"});
83217 (void)s_str.astype(std::string("datetime64[ns, UTC]"));
83218 };
83219
83220 bool caught_typed = false;
83221 bool caught_other = false;
83222 std::string other_what;
83223 try { invoke(); }
83224 catch (const pandas::TypeError&) { caught_typed = true; }
83225 catch (const std::exception& e) { caught_other = true; other_what = e.what(); }
seconds (pd_test_1_all.cpp:4192)
4182 void pd_test_timedelta_array_component_seconds() {
4183 std::cout << "========= TimedeltaArray: seconds component ======================= ";
4184
4185 pandas::TimedeltaArray arr({
4186 std::optional<numpy::timedelta64>(numpy::timedelta64(90, numpy::DateTimeUnit::Second)), // 90 secs
4187 std::optional<numpy::timedelta64>(numpy::timedelta64(3700, numpy::DateTimeUnit::Second)), // 1h + 100s
4188 std::nullopt
4189 });
4190
4191 auto secs = arr.seconds();
4192
4193 auto s0 = secs[0];
4194 if (!s0.has_value() || s0.value() != 90) {
4195 std::cout << " [FAIL] : seconds[0] should be 90" << std::endl;
4196 throw std::runtime_error("pd_test_timedelta_array_component_seconds failed: seconds[0]");
4197 }
4198
4199 auto s1 = secs[1];
4200 if (!s1.has_value() || s1.value() != 3700) {
4201 std::cout << " [FAIL] : seconds[1] should be 3700" << std::endl;
ss (pd_test_3_all.cpp:27670)
27660 fail++;
27661 } else {
27662 auto cats = str_s->get_cat_categories();
27663 if (cats.size() != 3) {
27664 std::cout << " FAIL: expected 3 categories, got " << cats.size() << std::endl;
27665 fail++;
27666 }
27667 }
27668 }
27669
27670 pandas::Series<std::string> ss({"a", "b", "a", "c"}, "strs");
27671 auto result2 = ss.astype("category");
27672 auto* str_s2 = dynamic_cast<pandas::Series<std::string>*>(result2.get());
27673 if (!str_s2) {
27674 std::cout << " FAIL: expected Series<string> for string->category" << std::endl;
27675 fail++;
27676 } else {
27677 if (str_s2->dtype_name() != "category") {
27678 std::cout << " FAIL: dtype should be category" << std::endl;
27679 fail++;
27680 }
toString (pd_test_1_all.cpp:9539)
9529void pd_test_timedelta_rounding_params() {
9530 std::cout << "========= Timedelta rounding with DST params =====";
9531
9532 // Create a Timedelta: 1h 30m 45s
9533 // Constructor is: (days, hours, minutes, seconds, ...)
9534 pandas::Timedelta td(0, 1, 30, 45); // 0 days, 1h, 30m, 45s
9535
9536 // Test floor with ambiguous/nonexistent params
9537 pandas::Timedelta floored = td.floor("h", "raise", "raise");
9538 std::cout << std::endl << " floor('h'): " << floored.toString();
9539
9540 // Test ceil with ambiguous/nonexistent params
9541 pandas::Timedelta ceiled = td.ceil("h", "raise", "raise");
9542 std::cout << std::endl << " ceil('h'): " << ceiled.toString();
9543
9544 // Test round with ambiguous/nonexistent params
9545 pandas::Timedelta rounded = td.round("h", "raise", "raise");
9546 std::cout << std::endl << " round('h'): " << rounded.toString();
9547
9548 // Verify results:
total_days (pd_test_timedelta_scalar.cpp:337)
327 double hrs = td.total_hours();
328 if (std::abs(hrs - 36.0) > 0.0001) {
329 std::cout << "[FAIL] np_test_timedelta_total_conversions: total_hours expected 36, got "
330 << hrs << std::endl;
331 errors++;
332 }
333 }
334
335 // total_days
336 {
337 double days = td.total_days();
338 if (std::abs(days - 1.5) > 0.0001) {
339 std::cout << "[FAIL] np_test_timedelta_total_conversions: total_days expected 1.5, got "
340 << days << std::endl;
341 errors++;
342 }
343 }
344
345 // value() and delta()
346 {
347 if (td.value() != td.delta()) {
total_hours (pd_test_timedelta_scalar.cpp:69)
59 << "got days=" << td.days() << " hours=" << td.hours()
60 << " minutes=" << td.minutes() << std::endl;
61 errors++;
62 }
63 }
64
65 // From timedelta64
66 {
67 numpy::timedelta64 td64(3600, numpy::DateTimeUnit::Second); // 1 hour
68 pandas::Timedelta td(td64);
69 if (std::abs(td.total_hours() - 1.0) > 0.0001) {
70 std::cout << "[FAIL] np_test_timedelta_constructors: from timedelta64 expected 1 hour, got "
71 << td.total_hours() << std::endl;
72 errors++;
73 }
74 }
75
76 // From std::chrono::duration
77 {
78 std::chrono::hours h(2);
79 pandas::Timedelta td(h);
total_minutes (pd_test_timedelta_scalar.cpp:106)
96 pandas::Timedelta td_days(3, "D"); // 3 days
97 std::cout << " Timedelta(3, 'D') = " << td_days.days() << " days" << std::endl;
98 if (td_days.days() != 3) {
99 std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(3, 'D') expected 3 days, got "
100 << td_days.days() << std::endl;
101 errors++;
102 }
103
104 pandas::Timedelta td_min(90, "min"); // 90 minutes = 1.5 hours
105 std::cout << " Timedelta(90, 'min') = " << td_min.total_minutes() << " minutes" << std::endl;
106 if (std::abs(td_min.total_minutes() - 90.0) > 0.0001) {
107 std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(90, 'min') expected 90 minutes, got "
108 << td_min.total_minutes() << std::endl;
109 errors++;
110 }
111
112 pandas::Timedelta td_sec(30, "s"); // 30 seconds
113 std::cout << " Timedelta(30, 's') = " << td_sec.total_seconds() << " seconds" << std::endl;
114 if (std::abs(td_sec.total_seconds() - 30.0) > 0.0001) {
115 std::cout << "[FAIL] np_test_timedelta_constructors: Timedelta(30, 's') expected 30 seconds, got "
total_seconds (pd_test_1_all.cpp:4224)
4214 void pd_test_timedelta_array_total_seconds() {
4215 std::cout << "========= TimedeltaArray: total_seconds ======================= ";
4216
4217 pandas::TimedeltaArray arr({
4218 std::optional<numpy::timedelta64>(numpy::timedelta64(1, numpy::DateTimeUnit::Day)),
4219 std::optional<numpy::timedelta64>(numpy::timedelta64(1, numpy::DateTimeUnit::Hour)),
4220 std::nullopt
4221 });
4222
4223 auto total = arr.total_seconds();
4224
4225 auto t0 = total[0];
4226 if (!t0.has_value() || std::abs(t0.value() - 86400.0) > 0.001) {
4227 std::cout << " [FAIL] : total_seconds[0] should be 86400" << std::endl;
4228 throw std::runtime_error("pd_test_timedelta_array_total_seconds failed: total_seconds[0]");
4229 }
4230
4231 auto t1 = total[1];
4232 if (!t1.has_value() || std::abs(t1.value() - 3600.0) > 0.001) {
4233 std::cout << " [FAIL] : total_seconds[1] should be 3600" << std::endl;
value (pd_test_1_all.cpp:88)
78 // T & T = T, T & F = F, T & NA = NA
79 // F & T = F, F & F = F, F & NA = F (False dominates)
80 // NA & T = NA, NA & F = F, NA & NA = NA
81
82 pandas::BooleanArray t({std::optional<bool>(true)});
83 pandas::BooleanArray f({std::optional<bool>(false)});
84 pandas::BooleanArray na({std::nullopt});
85
86 // T & T = T
87 auto tt = (t & t);
88 if (!tt[0].has_value() || !tt[0].value()) {
89 std::cout << " [FAIL] : in pd_test_boolean_array_kleene_and() : T & T should be T" << std::endl;
90 throw std::runtime_error("pd_test_boolean_array_kleene_and failed: T & T");
91 }
92
93 // T & F = F
94 auto tf = (t & f);
95 if (!tf[0].has_value() || tf[0].value()) {
96 std::cout << " [FAIL] : in pd_test_boolean_array_kleene_and() : T & F should be F" << std::endl;
97 throw std::runtime_error("pd_test_boolean_array_kleene_and failed: T & F");
98 }