DatetimeIndexOpsMixin#
-
class pandas::DatetimeIndexOpsMixin#
Mixin class providing shared functionality.
Example#
#include <pandas/pandas.h>
using namespace pandas;
// Create DatetimeIndexOpsMixin
DatetimeIndexOpsMixin<int64_t> idx({1, 2, 3}, "my_index");
size_t len = idx.size();
Constructors#
Signature |
Location |
Example |
|---|---|---|
|
pd_datetime_index_ops_mixin.h:140 |
|
|
pd_datetime_index_ops_mixin.h:150 |
|
|
pd_datetime_index_ops_mixin.h:159 |
|
|
pd_datetime_index_ops_mixin.h:167 |
Indexing / Selection#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
std::optional<std::string> |
pd_datetime_index_ops_mixin.h:216 |
Data Manipulation#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1474 |
Statistics#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
std::optional<value_type> |
pd_datetime_index_ops_mixin.h:1348 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:692 |
Time Series#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1273 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:423 |
|
|
ArrayType |
pd_datetime_index_ops_mixin.h:455 |
|
|
ArrayType |
pd_datetime_index_ops_mixin.h:477 |
|
|
PeriodArray |
pd_datetime_index_ops_mixin.h:1306 |
|
|
DatetimeArray |
pd_datetime_index_ops_mixin.h:1292 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1213 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1192 |
I/O#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
std::string |
pd_datetime_index_ops_mixin.h:1413 |
Conversion#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1467 |
Type Checking#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1116 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:962 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:934 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1146 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1134 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1024 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:992 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1087 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1058 |
|
|
BooleanArray |
pd_datetime_index_ops_mixin.h:1158 |
Other Methods#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:361 |
|
|
ArrayType |
pd_datetime_index_ops_mixin.h:390 |
|
|
std::unique_ptr<IndexBase> |
pd_datetime_index_ops_mixin.h:1402 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:666 |
|
|
std::vector<std::string> |
pd_datetime_index_ops_mixin.h:600 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:784 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:803 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:317 |
|
|
ArrayType |
pd_datetime_index_ops_mixin.h:346 |
|
|
static std::string |
pd_datetime_index_ops_mixin.h:1520 |
|
|
static std::string |
pd_datetime_index_ops_mixin.h:1546 |
|
|
std::optional<std::string> |
pd_datetime_index_ops_mixin.h:205 |
|
|
std::string |
pd_datetime_index_ops_mixin.h:228 |
|
|
pd_datetime_index_ops_mixin.h:1535 |
||
|
pd_datetime_index_ops_mixin.h:1533 |
||
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:678 |
|
|
std::optional<std::string> |
pd_datetime_index_ops_mixin.h:241 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:720 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:654 |
|
|
std::vector<std::string> |
pd_datetime_index_ops_mixin.h:553 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:753 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1177 |
|
|
static int64_t |
pd_datetime_index_ops_mixin.h:1495 |
|
|
static int64_t |
pd_datetime_index_ops_mixin.h:1561 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:815 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1198 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1216 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:1475 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:273 |
|
|
ArrayType |
pd_datetime_index_ops_mixin.h:302 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:706 |
|
|
void |
pd_datetime_index_ops_mixin.h:252 |
|
|
DatetimeIndexOpsMixin |
pd_datetime_index_ops_mixin.h:405 |
|
|
std::vector<std::string> |
pd_datetime_index_ops_mixin.h:501 |
|
|
IntegerArray<numpy::int64> |
pd_datetime_index_ops_mixin.h:870 |
|
|
IntegerArray<numpy::int64> |
pd_datetime_index_ops_mixin.h:894 |
|
|
IntegerArray<numpy::int64> |
pd_datetime_index_ops_mixin.h:906 |
|
|
IntegerArray<numpy::int64> |
pd_datetime_index_ops_mixin.h:882 |
|
|
FloatingArray<double> |
pd_datetime_index_ops_mixin.h:918 |
|
|
IndexTypeId |
pd_datetime_index_ops_mixin.h:1406 |
|
|
std::string |
pd_datetime_index_ops_mixin.h:1228 |
|
|
bool |
pd_datetime_index_ops_mixin.h:1254 |
|
|
std::string |
pd_datetime_index_ops_mixin.h:1241 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:827 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:795 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:858 |
|
|
IntegerArray<numpy::int32> |
pd_datetime_index_ops_mixin.h:642 |
Code Examples#
The following examples are extracted from the test suite.
get_freq (pd_test_2_all.cpp:20397)
20387 std::vector<numpy::datetime64> ts = {
20388 numpy::datetime64(0LL, numpy::DateTimeUnit::Day),
20389 numpy::datetime64(1LL, numpy::DateTimeUnit::Day),
20390 numpy::datetime64(2LL, numpy::DateTimeUnit::Day)
20391 };
20392 auto dt_idx = std::make_unique<pandas::DatetimeIndex>(ts);
20393 dt_idx->set_freq(std::string("D"));
20394 df.set_index(std::move(dt_idx));
20395
20396 auto s = df.extract_column_as_numeric_series("val");
20397 check(s.get_freq().has_value(), "freq propagated");
20398 if (s.get_freq().has_value()) {
20399 check(s.get_freq().value() == "D", "freq value D");
20400 }
20401
20402 // Test MultiIndex propagation
20403 pandas::DataFrame df2;
20404 std::vector<numpy::float64> vals2 = {10.0, 20.0};
20405 df2.insert(0, "A", std::make_unique<pandas::Series<numpy::float64>>(vals2, "A"), true);
20406 std::vector<std::vector<std::string>> arrays = {{"x", "y"}, {"1", "2"}};
20407 std::vector<std::optional<std::string>> names = {std::string("first"), std::string("second")};
rename (pd_test_1_all.cpp:5816)
5806 std::cout << " -> tests passed" << std::endl;
5807}
5808
5809void pd_test_categorical_index_rename() {
5810 std::cout << "========= rename ======================================";
5811
5812 pandas::CategoricalArray arr({"x", "y"});
5813 pandas::CategoricalIndex idx(arr, "old_name");
5814
5815 pandas::CategoricalIndex renamed = idx.rename("new_name");
5816
5817 bool passed = (renamed.name().has_value() && *renamed.name() == "new_name" &&
5818 renamed.size() == idx.size() && renamed.categories() == idx.categories());
5819 if (!passed) {
5820 std::cout << " [FAIL] : in pd_test_categorical_index_rename()" << std::endl;
5821 throw std::runtime_error("pd_test_categorical_index_rename failed");
5822 }
5823
5824 std::cout << " -> tests passed" << std::endl;
5825}
mean (pd_test_1_all.cpp:282)
272 std::optional<bool>(true),
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 ======================= ";
minute (pd_test_1_all.cpp:7505)
7495 std::cout << "========= minute property =============================";
7496
7497 std::vector<std::optional<numpy::datetime64>> values = {
7498 make_dt(0), // Minute 0
7499 make_dt(30 * NS_PER_MIN), // Minute 30
7500 make_dt(59 * NS_PER_MIN) // Minute 59
7501 };
7502 pandas::DatetimeArray arr(values);
7503 pandas::DatetimeIndex idx(arr);
7504
7505 auto minutes = idx.minute();
7506
7507 bool passed = (minutes.size() == 3);
7508 auto m0 = minutes[0];
7509 auto m1 = minutes[1];
7510 auto m2 = minutes[2];
7511 passed = passed && m0.has_value() && *m0 == 0;
7512 passed = passed && m1.has_value() && *m1 == 30;
7513 passed = passed && m2.has_value() && *m2 == 59;
7514
7515 if (!passed) {
asfreq (pd_test_1_all.cpp:2869)
2859 std::cout << "========= PeriodArray: asfreq ======================= ";
2860
2861 // Monthly to quarterly
2862 pandas::PeriodArray arr_m(std::vector<std::string>{
2863 "2024-01",
2864 "2024-04",
2865 "2024-07",
2866 "NaT"
2867 }, "M");
2868
2869 auto arr_q = arr_m.asfreq("Q");
2870 if (arr_q.size() != 4) {
2871 std::cout << " [FAIL] : asfreq size should be 4" << std::endl;
2872 throw std::runtime_error("pd_test_period_array_asfreq failed: size");
2873 }
2874 if (arr_q.freqstr() != "Q") {
2875 std::cout << " [FAIL] : asfreq freqstr should be 'Q'" << std::endl;
2876 throw std::runtime_error("pd_test_period_array_asfreq failed: freqstr");
2877 }
2878
2879 // Check NaT is preserved
shift (pd_test_1_all.cpp:5188)
5178 // First element should be NaN
5179 val = d["A"].get_value_str(0);
5180 passed = std::isnan(std::stod(val));
5181 if (!passed) {
5182 std::cout << " [FAIL] : in pd_test_arithmetic_dataframe_diff_shift() : diff NaN failed" << std::endl;
5183 throw std::runtime_error("pd_test_arithmetic_dataframe_diff_shift failed: diff NaN failed");
5184 }
5185
5186 // shift: [NaN, 1, 3, 6]
5187 auto s = df.shift();
5188 val = s["A"].get_value_str(1);
5189 passed = std::abs(std::stod(val) - 1.0) < 0.001;
5190 if (!passed) {
5191 std::cout << " [FAIL] : in pd_test_arithmetic_dataframe_diff_shift() : shift failed" << std::endl;
5192 throw std::runtime_error("pd_test_arithmetic_dataframe_diff_shift failed: shift failed");
5193 }
5194
5195 std::cout << " -> tests passed" << std::endl;
5196 }
to_period (pd_test_2_all.cpp:14554)
14544 std::cout << "====================================== [OK] pd_test_to_parquet test suite ========================" << std::endl;
14545 return 0;
14546 }
14547
14548} // namespace dataframe_tests
14549// ------------------- pd_test_to_parquet.cpp (end) -----------------------------
14550
14551// ------------------- pd_test_to_period.cpp (start) -----------------------------
14552// dataframe_tests/pd_test_to_period.cpp
14553// Test suite for DataFrame.to_period() method
14554
14555#include <iostream>
14556#include <stdexcept>
14557#include <vector>
14558#include <string>
14559#include <map>
14560
14561#include "../pandas/pd_dataframe.h"
14562
14563// CRITICAL: No using namespace directives
to_timestamp (pd_test_1_all.cpp:2830)
2820 void pd_test_period_array_to_timestamp() {
2821 std::cout << "========= PeriodArray: to_timestamp ======================= ";
2822
2823 pandas::PeriodArray arr(std::vector<std::string>{
2824 "2024-01",
2825 "2024-06",
2826 "NaT"
2827 }, "M");
2828
2829 // to_timestamp with start
2830 auto ts_start = arr.to_timestamp("start");
2831 if (ts_start.size() != 3) {
2832 std::cout << " [FAIL] : to_timestamp size should be 3" << std::endl;
2833 throw std::runtime_error("pd_test_period_array_to_timestamp failed: size");
2834 }
2835
2836 auto ts0 = ts_start[0];
2837 if (!ts0.has_value()) {
2838 std::cout << " [FAIL] : ts_start[0] should have value" << std::endl;
2839 throw std::runtime_error("pd_test_period_array_to_timestamp failed: ts_start[0]");
2840 }
tz_convert (pd_test_2_all.cpp:17874)
17864 std::cout << "====================================== [OK] pd_test_transform test suite ========================== " << std::endl;
17865 return 0;
17866 }
17867
17868} // namespace dataframe_tests
17869// ------------------- pd_test_transform.cpp (end) -----------------------------
17870
17871// ------------------- pd_test_tz_convert.cpp (start) -----------------------------
17872// dataframe_tests/pd_test_tz_convert.cpp
17873// Test for DataFrame.tz_convert() method
17874
17875#include <iostream>
17876#include <stdexcept>
17877#include <cmath>
17878#include "../pandas/pd_dataframe.h"
17879
17880namespace dataframe_tests {
17881 namespace dataframe_tests_tz_convert {
17882
17883 void pd_test_tz_convert_basic() {
tz_localize (pd_test_1_all.cpp:1431)
1421 "2023-06-15"
1422 });
1423
1424 // Initially should be timezone-naive
1425 if (arr.is_tz_aware()) {
1426 std::cout << " [FAIL] : array should be timezone-naive initially" << std::endl;
1427 throw std::runtime_error("pd_test_datetime_array_timezone failed: naive");
1428 }
1429
1430 // Localize to UTC
1431 auto localized = arr.tz_localize("UTC");
1432 if (!localized.is_tz_aware()) {
1433 std::cout << " [FAIL] : localized array should be timezone-aware" << std::endl;
1434 throw std::runtime_error("pd_test_datetime_array_timezone failed: localize");
1435 }
1436
1437 // Verify timezone name in dtype
1438 auto dt = localized.dtype();
1439 if (!dt.is_tz_aware()) {
1440 std::cout << " [FAIL] : dtype should be timezone-aware" << std::endl;
1441 throw std::runtime_error("pd_test_datetime_array_timezone failed: dtype tz");
to_string (pd_test_1_all.cpp:2693)
2683 pandas::PeriodArray arr_m(std::vector<std::string>{
2684 "2020-01",
2685 "NaT",
2686 "2025-06"
2687 }, "M");
2688
2689 // Year
2690 auto years = arr_m.year();
2691 auto y0 = years[0];
2692 if (!y0.has_value() || y0.value() != 2020) {
2693 std::cout << " [FAIL] : year[0] should be 2020, got " << (y0.has_value() ? std::to_string(y0.value()) : "NA") << std::endl;
2694 throw std::runtime_error("pd_test_period_array_year_month_quarter failed: year[0]");
2695 }
2696
2697 auto y1 = years[1];
2698 if (y1.has_value()) {
2699 std::cout << " [FAIL] : year[1] should be NA (NaT)" << std::endl;
2700 throw std::runtime_error("pd_test_period_array_year_month_quarter failed: year[1] should be NA");
2701 }
2702
2703 auto y2 = years[2];
copy (pd_test_1_all.cpp:5798)
5788// ============================================================================
5789// Copy/Rename Tests
5790// ============================================================================
5791
5792void pd_test_categorical_index_copy() {
5793 std::cout << "========= copy ========================================";
5794
5795 pandas::CategoricalArray arr({"a", "b", "c"});
5796 pandas::CategoricalIndex idx(arr, "original");
5797
5798 pandas::CategoricalIndex copied = idx.copy();
5799
5800 bool passed = (copied.size() == idx.size() && copied.name() == idx.name() &&
5801 copied.categories() == idx.categories() && copied.ordered() == idx.ordered());
5802 if (!passed) {
5803 std::cout << " [FAIL] : in pd_test_categorical_index_copy()" << std::endl;
5804 throw std::runtime_error("pd_test_categorical_index_copy failed");
5805 }
5806
5807 std::cout << " -> tests passed" << std::endl;
5808}
is_leap_year (pd_test_1_all.cpp:1280)
1270 }
1271
1272 // is_month_end
1273 auto me = arr.is_month_end();
1274 if (!me[1].has_value() || !me[1].value()) {
1275 std::cout << " [FAIL] : 2023-03-31 should be month end" << std::endl;
1276 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end");
1277 }
1278
1279 // is_leap_year
1280 auto ly = arr.is_leap_year();
1281 if (!ly[2].has_value() || !ly[2].value()) {
1282 std::cout << " [FAIL] : 2024 should be leap year" << std::endl;
1283 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: leap year");
1284 }
1285 if (!ly[0].has_value() || ly[0].value()) {
1286 std::cout << " [FAIL] : 2023 should not be leap year" << std::endl;
1287 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not leap year");
1288 }
1289
1290 std::cout << " -> tests passed" << std::endl;
is_month_end (pd_test_1_all.cpp:1273)
1263 }
1264
1265 // is_month_start
1266 auto ms = arr.is_month_start();
1267 if (!ms[0].has_value() || !ms[0].value()) {
1268 std::cout << " [FAIL] : 2023-01-01 should be month start" << std::endl;
1269 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month start");
1270 }
1271
1272 // is_month_end
1273 auto me = arr.is_month_end();
1274 if (!me[1].has_value() || !me[1].value()) {
1275 std::cout << " [FAIL] : 2023-03-31 should be month end" << std::endl;
1276 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end");
1277 }
1278
1279 // is_leap_year
1280 auto ly = arr.is_leap_year();
1281 if (!ly[2].has_value() || !ly[2].value()) {
1282 std::cout << " [FAIL] : 2024 should be leap year" << std::endl;
1283 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: leap year");
is_month_start (pd_test_1_all.cpp:1266)
1256 if (!ys[0].has_value() || !ys[0].value()) {
1257 std::cout << " [FAIL] : 2023-01-01 should be year start" << std::endl;
1258 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: year start");
1259 }
1260 if (!ys[1].has_value() || ys[1].value()) {
1261 std::cout << " [FAIL] : 2023-03-31 should not be year start" << std::endl;
1262 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not year start");
1263 }
1264
1265 // is_month_start
1266 auto ms = arr.is_month_start();
1267 if (!ms[0].has_value() || !ms[0].value()) {
1268 std::cout << " [FAIL] : 2023-01-01 should be month start" << std::endl;
1269 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month start");
1270 }
1271
1272 // is_month_end
1273 auto me = arr.is_month_end();
1274 if (!me[1].has_value() || !me[1].value()) {
1275 std::cout << " [FAIL] : 2023-03-31 should be month end" << std::endl;
1276 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: month end");
is_negative (pd_test_1_all.cpp:4269)
4259 if (!pos[0].has_value() || !pos[0].value()) {
4260 std::cout << " [FAIL] : 1 day should be positive" << std::endl;
4261 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_positive");
4262 }
4263 if (!pos[1].has_value() || pos[1].value()) {
4264 std::cout << " [FAIL] : -5 hours should not be positive" << std::endl;
4265 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not positive");
4266 }
4267
4268 // is_negative
4269 auto neg = arr.is_negative();
4270 if (!neg[1].has_value() || !neg[1].value()) {
4271 std::cout << " [FAIL] : -5 hours should be negative" << std::endl;
4272 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_negative");
4273 }
4274 if (!neg[0].has_value() || neg[0].value()) {
4275 std::cout << " [FAIL] : 1 day should not be negative" << std::endl;
4276 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not negative");
4277 }
4278
4279 // is_zero
is_positive (pd_test_1_all.cpp:4258)
4248 std::cout << "========= TimedeltaArray: boolean properties ======================= ";
4249
4250 pandas::TimedeltaArray arr({
4251 std::optional<numpy::timedelta64>(numpy::timedelta64(1, numpy::DateTimeUnit::Day)), // positive
4252 std::optional<numpy::timedelta64>(numpy::timedelta64(-5, numpy::DateTimeUnit::Hour)), // negative
4253 std::optional<numpy::timedelta64>(numpy::timedelta64(0, numpy::DateTimeUnit::Second)), // zero
4254 std::nullopt
4255 });
4256
4257 // is_positive
4258 auto pos = arr.is_positive();
4259 if (!pos[0].has_value() || !pos[0].value()) {
4260 std::cout << " [FAIL] : 1 day should be positive" << std::endl;
4261 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_positive");
4262 }
4263 if (!pos[1].has_value() || pos[1].value()) {
4264 std::cout << " [FAIL] : -5 hours should not be positive" << std::endl;
4265 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not positive");
4266 }
4267
4268 // is_negative
is_quarter_end (pd_test_3_all.cpp:25056)
25046 };
25047 pandas::Series<numpy::datetime64> s(dates);
25048 pandas::DatetimeProperties<pandas::Series<numpy::datetime64>> dt(s);
25049 if (dt.has_nat()) throw std::runtime_error("has_nat should be false for clean series");
25050 auto ms = dt.is_month_start();
25051 if (ms[0] != true || ms[1] != false) throw std::runtime_error("is_month_start failed");
25052 auto me = dt.is_month_end();
25053 if (me[1] != true || me[0] != false) throw std::runtime_error("is_month_end failed");
25054 auto qs = dt.is_quarter_start();
25055 if (qs[0] != true || qs[1] != false) throw std::runtime_error("is_quarter_start failed");
25056 auto qe = dt.is_quarter_end();
25057 if (qe[2] != true || qe[0] != false) throw std::runtime_error("is_quarter_end failed");
25058 auto ys = dt.is_year_start();
25059 if (ys[0] != true || ys[1] != false) throw std::runtime_error("is_year_start failed");
25060 auto ye = dt.is_year_end();
25061 if (ye[3] != true || ye[0] != false) throw std::runtime_error("is_year_end failed");
25062 std::cout << " -> tests passed" << std::endl;
25063}
25064
25065void pd_test_dt_bool_na_with_nat() {
25066 std::cout << "========= pd_test_dt_bool_na: series with NaT ==========";
is_quarter_start (pd_test_3_all.cpp:25054)
25044 numpy::datetime64("2024-03-31"),
25045 numpy::datetime64("2024-12-31")
25046 };
25047 pandas::Series<numpy::datetime64> s(dates);
25048 pandas::DatetimeProperties<pandas::Series<numpy::datetime64>> dt(s);
25049 if (dt.has_nat()) throw std::runtime_error("has_nat should be false for clean series");
25050 auto ms = dt.is_month_start();
25051 if (ms[0] != true || ms[1] != false) throw std::runtime_error("is_month_start failed");
25052 auto me = dt.is_month_end();
25053 if (me[1] != true || me[0] != false) throw std::runtime_error("is_month_end failed");
25054 auto qs = dt.is_quarter_start();
25055 if (qs[0] != true || qs[1] != false) throw std::runtime_error("is_quarter_start failed");
25056 auto qe = dt.is_quarter_end();
25057 if (qe[2] != true || qe[0] != false) throw std::runtime_error("is_quarter_end failed");
25058 auto ys = dt.is_year_start();
25059 if (ys[0] != true || ys[1] != false) throw std::runtime_error("is_year_start failed");
25060 auto ye = dt.is_year_end();
25061 if (ye[3] != true || ye[0] != false) throw std::runtime_error("is_year_end failed");
25062 std::cout << " -> tests passed" << std::endl;
25063}
is_year_end (pd_test_3_all.cpp:25060)
25050 auto ms = dt.is_month_start();
25051 if (ms[0] != true || ms[1] != false) throw std::runtime_error("is_month_start failed");
25052 auto me = dt.is_month_end();
25053 if (me[1] != true || me[0] != false) throw std::runtime_error("is_month_end failed");
25054 auto qs = dt.is_quarter_start();
25055 if (qs[0] != true || qs[1] != false) throw std::runtime_error("is_quarter_start failed");
25056 auto qe = dt.is_quarter_end();
25057 if (qe[2] != true || qe[0] != false) throw std::runtime_error("is_quarter_end failed");
25058 auto ys = dt.is_year_start();
25059 if (ys[0] != true || ys[1] != false) throw std::runtime_error("is_year_start failed");
25060 auto ye = dt.is_year_end();
25061 if (ye[3] != true || ye[0] != false) throw std::runtime_error("is_year_end failed");
25062 std::cout << " -> tests passed" << std::endl;
25063}
25064
25065void pd_test_dt_bool_na_with_nat() {
25066 std::cout << "========= pd_test_dt_bool_na: series with NaT ==========";
25067 std::vector<numpy::datetime64> dates = {
25068 numpy::datetime64("2024-01-01"),
25069 numpy::datetime64(), // NaT
25070 numpy::datetime64("2024-12-31")
is_year_start (pd_test_1_all.cpp:1255)
1245 std::cout << "========= DatetimeArray: boolean properties ======================= ";
1246
1247 pandas::DatetimeArray arr(std::vector<std::string>{
1248 "2023-01-01", // year start, month start
1249 "2023-03-31", // quarter end, month end
1250 "2024-02-29", // leap year (2024 is leap year)
1251 "2023-12-31" // year end, month end
1252 });
1253
1254 // is_year_start
1255 auto ys = arr.is_year_start();
1256 if (!ys[0].has_value() || !ys[0].value()) {
1257 std::cout << " [FAIL] : 2023-01-01 should be year start" << std::endl;
1258 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: year start");
1259 }
1260 if (!ys[1].has_value() || ys[1].value()) {
1261 std::cout << " [FAIL] : 2023-03-31 should not be year start" << std::endl;
1262 throw std::runtime_error("pd_test_datetime_array_boolean_props failed: not year start");
1263 }
1264
1265 // is_month_start
is_zero (pd_test_1_all.cpp:4280)
4270 if (!neg[1].has_value() || !neg[1].value()) {
4271 std::cout << " [FAIL] : -5 hours should be negative" << std::endl;
4272 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_negative");
4273 }
4274 if (!neg[0].has_value() || neg[0].value()) {
4275 std::cout << " [FAIL] : 1 day should not be negative" << std::endl;
4276 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: not negative");
4277 }
4278
4279 // is_zero
4280 auto zero = arr.is_zero();
4281 if (!zero[2].has_value() || !zero[2].value()) {
4282 std::cout << " [FAIL] : 0 seconds should be zero" << std::endl;
4283 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: is_zero");
4284 }
4285
4286 // NA should propagate
4287 if (pos[3].has_value() || neg[3].has_value() || zero[3].has_value()) {
4288 std::cout << " [FAIL] : NaT should propagate to boolean props" << std::endl;
4289 throw std::runtime_error("pd_test_timedelta_array_boolean_props failed: NaT propagation");
4290 }
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;
clone (pd_test_1_all.cpp:5776)
5766 std::cout << " -> tests passed" << std::endl;
5767}
5768
5769void pd_test_categorical_index_clone() {
5770 std::cout << "========= clone =======================================";
5771
5772 pandas::CategoricalArray arr({"p", "q", "r"});
5773 pandas::CategoricalIndex idx(arr, "original");
5774
5775 std::unique_ptr<pandas::IndexBase> cloned = idx.clone();
5776
5777 bool passed = (cloned != nullptr && cloned->size() == idx.size() &&
5778 cloned->name() == idx.name());
5779 if (!passed) {
5780 std::cout << " [FAIL] : in pd_test_categorical_index_clone()" << std::endl;
5781 throw std::runtime_error("pd_test_categorical_index_clone failed");
5782 }
5783
5784 std::cout << " -> tests passed" << std::endl;
5785}
day (pd_test_1_all.cpp:1193)
1183 std::cout << " [FAIL] : month[0] should be 3" << std::endl;
1184 throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[0]");
1185 }
1186 auto m1 = months[1];
1187 if (!m1.has_value() || m1.value() != 12) {
1188 std::cout << " [FAIL] : month[1] should be 12" << std::endl;
1189 throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[1]");
1190 }
1191
1192 // Day
1193 auto days = arr.day();
1194 auto d0 = days[0];
1195 if (!d0.has_value() || d0.value() != 15) {
1196 std::cout << " [FAIL] : day[0] should be 15" << std::endl;
1197 throw std::runtime_error("pd_test_datetime_array_component_month_day failed: day[0]");
1198 }
1199 auto d1 = days[1];
1200 if (!d1.has_value() || d1.value() != 25) {
1201 std::cout << " [FAIL] : day[1] should be 25" << std::endl;
1202 throw std::runtime_error("pd_test_datetime_array_component_month_day failed: day[1]");
1203 }
day_name (pd_test_1_all.cpp:8474)
8464void pd_test_datetime_mixin_day_name() {
8465 std::cout << "========= day_name ====================================";
8466
8467 std::vector<std::optional<numpy::datetime64>> values = {
8468 numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond) // 1970-01-01 = Thursday
8469 };
8470 pandas::DatetimeArray arr(values);
8471 pandas::DatetimeMixinIndex idx(arr);
8472
8473 std::vector<std::string> names = idx.day_name();
8474
8475 bool passed = (names.size() == 1 && names[0] == "Thursday");
8476 if (!passed) {
8477 std::cout << " [FAIL] : in pd_test_datetime_mixin_day_name() got: " << names[0] << std::endl;
8478 throw std::runtime_error("pd_test_datetime_mixin_day_name failed");
8479 }
8480
8481 std::cout << " -> tests passed" << std::endl;
8482}
dayofweek (pd_test_1_all.cpp:7565)
7555 // 1970-01-01 was a Thursday (day 3)
7556 std::vector<std::optional<numpy::datetime64>> values = {
7557 make_dt(0), // Thursday (3)
7558 make_dt(NS_PER_DAY), // Friday (4)
7559 make_dt(2 * NS_PER_DAY), // Saturday (5)
7560 make_dt(3 * NS_PER_DAY) // Sunday (6)
7561 };
7562 pandas::DatetimeArray arr(values);
7563 pandas::DatetimeIndex idx(arr);
7564
7565 auto dow = idx.dayofweek();
7566
7567 bool passed = (dow.size() == 4);
7568 if (!passed) {
7569 std::cout << " [FAIL] : in pd_test_datetime_index_dayofweek()" << std::endl;
7570 throw std::runtime_error("pd_test_datetime_index_dayofweek failed");
7571 }
7572
7573 std::cout << " -> tests passed" << std::endl;
7574}
dayofyear (pd_test_3_all.cpp:18582)
18572 auto seconds = s.dt().second();
18573 if (seconds[0] != 45 || seconds[1] != 30 || seconds[2] != 59) {
18574 std::cout << " [FAIL] : second() failed" << std::endl;
18575 throw std::runtime_error("pd_test_dt_time_components: second() failed");
18576 }
18577
18578 std::cout << " -> tests passed" << std::endl;
18579}
18580
18581// ============================================================================
18582// Test dt().dayofweek(), dt().dayofyear(), dt().quarter()
18583// ============================================================================
18584
18585void pd_test_dt_derived_properties() {
18586 std::cout << "========= Series.dt().dayofweek/dayofyear/quarter() ======";
18587
18588 // 2020-01-01 is a Wednesday (dayofweek=2), dayofyear=1, Q1
18589 // 2020-07-04 is a Saturday (dayofweek=5), dayofyear=186, Q3
18590 pandas::Series<std::string> s({"2020-01-01", "2020-07-04"});
18591
18592 auto dow = s.dt().dayofweek();
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;
freq (pd_test_1_all.cpp:8233)
8223 std::cout << "========= freq property ===============================";
8224
8225 std::vector<std::optional<numpy::datetime64>> values = {
8226 numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond),
8227 numpy::datetime64(86400000000000LL, numpy::DateTimeUnit::Nanosecond) // 1 day
8228 };
8229 pandas::DatetimeArray arr(values);
8230 pandas::DatetimeMixinIndex idx(arr);
8231
8232 // Default freq is nullopt or inferred
8233 auto f = idx.freq();
8234 std::string fs = idx.freqstr();
8235
8236 bool passed = true; // freq may or may not be set
8237 if (!passed) {
8238 std::cout << " [FAIL] : in pd_test_datetime_mixin_freq()" << std::endl;
8239 throw std::runtime_error("pd_test_datetime_mixin_freq failed");
8240 }
8241
8242 std::cout << " -> tests passed" << std::endl;
8243}
freqstr (pd_test_1_all.cpp:2671)
2661 }
2662
2663 pandas::PeriodDtype dtype_y("Y");
2664 if (dtype_y.name() != "period[Y]") {
2665 std::cout << " [FAIL] : dtype_y.name() should be 'period[Y]'" << std::endl;
2666 throw std::runtime_error("pd_test_period_array_freq_validation failed: dtype name Y");
2667 }
2668
2669 // Test frequency string
2670 pandas::PeriodArray arr(std::vector<std::string>{"2024-01-15"}, "D");
2671 if (arr.freqstr() != "D") {
2672 std::cout << " [FAIL] : arr.freqstr() should be 'D'" << std::endl;
2673 throw std::runtime_error("pd_test_period_array_freq_validation failed: freqstr");
2674 }
2675
2676 std::cout << " -> tests passed" << std::endl;
2677 }
2678
2679 void pd_test_period_array_year_month_quarter() {
2680 std::cout << "========= PeriodArray: year/month/quarter components ======================= ";
hour (pd_test_1_all.cpp:7476)
7466 std::cout << "========= hour property ===============================";
7467
7468 std::vector<std::optional<numpy::datetime64>> values = {
7469 make_dt(0), // Hour 0
7470 make_dt(6 * NS_PER_HOUR), // Hour 6
7471 make_dt(23 * NS_PER_HOUR) // Hour 23
7472 };
7473 pandas::DatetimeArray arr(values);
7474 pandas::DatetimeIndex idx(arr);
7475
7476 auto hours = idx.hour();
7477
7478 bool passed = (hours.size() == 3);
7479 auto h0 = hours[0];
7480 auto h1 = hours[1];
7481 auto h2 = hours[2];
7482 passed = passed && h0.has_value() && *h0 == 0;
7483 passed = passed && h1.has_value() && *h1 == 6;
7484 passed = passed && h2.has_value() && *h2 == 23;
7485
7486 if (!passed) {
microsecond (pd_test_timestamp_scalar.cpp:45)
35 // Component constructor
36 pandas::Timestamp ts1(2024, 6, 15, 14, 30, 45);
37 if (ts1.year() != 2024 || ts1.month() != 6 || ts1.day() != 15 ||
38 ts1.hour() != 14 || ts1.minute() != 30 || ts1.second() != 45) {
39 pass = false;
40 fail_msg = "Component constructor values incorrect";
41 }
42
43 // With microseconds and nanoseconds
44 pandas::Timestamp ts2(2024, 1, 1, 12, 0, 0, 123456, 789);
45 if (ts2.microsecond() != 123456 || ts2.nanosecond() != 789) {
46 pass = false;
47 fail_msg = "Microsecond/nanosecond values incorrect";
48 }
49
50 // String constructor - ISO format
51 pandas::Timestamp ts3("2024-06-15T14:30:45");
52 if (ts3.year() != 2024 || ts3.month() != 6 || ts3.day() != 15) {
53 pass = false;
54 fail_msg = "String constructor parse failed";
55 }
month (pd_test_1_all.cpp:1180)
1170 void pd_test_datetime_array_component_month_day() {
1171 std::cout << "========= DatetimeArray: month/day components ======================= ";
1172
1173 pandas::DatetimeArray arr(std::vector<std::string>{
1174 "2023-03-15",
1175 "2023-12-25",
1176 "NaT"
1177 });
1178
1179 // Month
1180 auto months = arr.month();
1181 auto m0 = months[0];
1182 if (!m0.has_value() || m0.value() != 3) {
1183 std::cout << " [FAIL] : month[0] should be 3" << std::endl;
1184 throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[0]");
1185 }
1186 auto m1 = months[1];
1187 if (!m1.has_value() || m1.value() != 12) {
1188 std::cout << " [FAIL] : month[1] should be 12" << std::endl;
1189 throw std::runtime_error("pd_test_datetime_array_component_month_day failed: month[1]");
1190 }
month_name (pd_test_1_all.cpp:8454)
8444void pd_test_datetime_mixin_month_name() {
8445 std::cout << "========= month_name ==================================";
8446
8447 std::vector<std::optional<numpy::datetime64>> values = {
8448 numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond) // 1970-01-01 = January
8449 };
8450 pandas::DatetimeArray arr(values);
8451 pandas::DatetimeMixinIndex idx(arr);
8452
8453 std::vector<std::string> names = idx.month_name();
8454
8455 bool passed = (names.size() == 1 && names[0] == "January");
8456 if (!passed) {
8457 std::cout << " [FAIL] : in pd_test_datetime_mixin_month_name() got: " << names[0] << std::endl;
8458 throw std::runtime_error("pd_test_datetime_mixin_month_name failed");
8459 }
8460
8461 std::cout << " -> tests passed" << std::endl;
8462}
nanosecond (pd_test_timestamp_scalar.cpp:45)
35 // Component constructor
36 pandas::Timestamp ts1(2024, 6, 15, 14, 30, 45);
37 if (ts1.year() != 2024 || ts1.month() != 6 || ts1.day() != 15 ||
38 ts1.hour() != 14 || ts1.minute() != 30 || ts1.second() != 45) {
39 pass = false;
40 fail_msg = "Component constructor values incorrect";
41 }
42
43 // With microseconds and nanoseconds
44 pandas::Timestamp ts2(2024, 1, 1, 12, 0, 0, 123456, 789);
45 if (ts2.microsecond() != 123456 || ts2.nanosecond() != 789) {
46 pass = false;
47 fail_msg = "Microsecond/nanosecond values incorrect";
48 }
49
50 // String constructor - ISO format
51 pandas::Timestamp ts3("2024-06-15T14:30:45");
52 if (ts3.year() != 2024 || ts3.month() != 6 || ts3.day() != 15) {
53 pass = false;
54 fail_msg = "String constructor parse failed";
55 }
normalize (pd_test_1_all.cpp:8723)
8713void pd_test_datetime_mixin_normalize() {
8714 std::cout << "========= normalize ===================================";
8715
8716 // Create datetime with time component
8717 std::vector<std::optional<numpy::datetime64>> values = {
8718 numpy::datetime64(86400000000000LL + 3600000000000LL, numpy::DateTimeUnit::Nanosecond) // 1 day + 1 hour
8719 };
8720 pandas::DatetimeArray arr(values);
8721 pandas::DatetimeMixinIndex idx(arr);
8722
8723 pandas::DatetimeMixinIndex normalized = idx.normalize();
8724
8725 bool passed = (normalized.size() == 1);
8726 if (!passed) {
8727 std::cout << " [FAIL] : in pd_test_datetime_mixin_normalize()" << std::endl;
8728 throw std::runtime_error("pd_test_datetime_mixin_normalize failed");
8729 }
8730
8731 std::cout << " -> tests passed" << std::endl;
8732}
quarter (pd_test_1_all.cpp:1218)
1208 void pd_test_datetime_array_quarter() {
1209 std::cout << "========= DatetimeArray: quarter ======================= ";
1210
1211 pandas::DatetimeArray arr(std::vector<std::string>{
1212 "2023-01-15", // Q1
1213 "2023-05-20", // Q2
1214 "2023-09-10", // Q3
1215 "2023-11-25" // Q4
1216 });
1217
1218 auto quarters = arr.quarter();
1219
1220 auto q0 = quarters[0];
1221 if (!q0.has_value() || q0.value() != 1) {
1222 std::cout << " [FAIL] : quarter[0] should be 1" << std::endl;
1223 throw std::runtime_error("pd_test_datetime_array_quarter failed: quarter[0]");
1224 }
1225 auto q1 = quarters[1];
1226 if (!q1.has_value() || q1.value() != 2) {
1227 std::cout << " [FAIL] : quarter[1] should be 2" << std::endl;
1228 throw std::runtime_error("pd_test_datetime_array_quarter failed: quarter[1]");
result (pd_test_1_all.cpp:15406)
15396 data.setElementAt({0}, numpy::datetime64(100LL, numpy::DateTimeUnit::Nanosecond));
15397 data.setElementAt({1}, numpy::datetime64(200LL, numpy::DateTimeUnit::Nanosecond));
15398
15399 numpy::NDArray<numpy::bool_> mask(std::vector<size_t>{2});
15400 mask.setElementAt({0}, numpy::bool_(false));
15401 mask.setElementAt({1}, numpy::bool_(false));
15402
15403 pandas::DatetimeArray arr(data, mask);
15404 pandas::DatetimeIndexBase idx(arr, "original");
15405
15406 // Create join result (int64 values)
15407 numpy::NDArray<numpy::int64> join_result(std::vector<size_t>{3});
15408 join_result.setElementAt({0}, numpy::int64(500LL));
15409 join_result.setElementAt({1}, numpy::int64(600LL));
15410 join_result.setElementAt({2}, numpy::int64(700LL));
15411
15412 auto new_idx = idx._from_join_target(join_result);
15413
15414 bool passed = (new_idx.size() == 3 &&
15415 new_idx.name().has_value() && *new_idx.name() == "original");
15416 if (!passed) {
result (pd_test_1_all.cpp:15406)
15396 data.setElementAt({0}, numpy::datetime64(100LL, numpy::DateTimeUnit::Nanosecond));
15397 data.setElementAt({1}, numpy::datetime64(200LL, numpy::DateTimeUnit::Nanosecond));
15398
15399 numpy::NDArray<numpy::bool_> mask(std::vector<size_t>{2});
15400 mask.setElementAt({0}, numpy::bool_(false));
15401 mask.setElementAt({1}, numpy::bool_(false));
15402
15403 pandas::DatetimeArray arr(data, mask);
15404 pandas::DatetimeIndexBase idx(arr, "original");
15405
15406 // Create join result (int64 values)
15407 numpy::NDArray<numpy::int64> join_result(std::vector<size_t>{3});
15408 join_result.setElementAt({0}, numpy::int64(500LL));
15409 join_result.setElementAt({1}, numpy::int64(600LL));
15410 join_result.setElementAt({2}, numpy::int64(700LL));
15411
15412 auto new_idx = idx._from_join_target(join_result);
15413
15414 bool passed = (new_idx.size() == 3 &&
15415 new_idx.name().has_value() && *new_idx.name() == "original");
15416 if (!passed) {
result (pd_test_1_all.cpp:15406)
15396 data.setElementAt({0}, numpy::datetime64(100LL, numpy::DateTimeUnit::Nanosecond));
15397 data.setElementAt({1}, numpy::datetime64(200LL, numpy::DateTimeUnit::Nanosecond));
15398
15399 numpy::NDArray<numpy::bool_> mask(std::vector<size_t>{2});
15400 mask.setElementAt({0}, numpy::bool_(false));
15401 mask.setElementAt({1}, numpy::bool_(false));
15402
15403 pandas::DatetimeArray arr(data, mask);
15404 pandas::DatetimeIndexBase idx(arr, "original");
15405
15406 // Create join result (int64 values)
15407 numpy::NDArray<numpy::int64> join_result(std::vector<size_t>{3});
15408 join_result.setElementAt({0}, numpy::int64(500LL));
15409 join_result.setElementAt({1}, numpy::int64(600LL));
15410 join_result.setElementAt({2}, numpy::int64(700LL));
15411
15412 auto new_idx = idx._from_join_target(join_result);
15413
15414 bool passed = (new_idx.size() == 3 &&
15415 new_idx.name().has_value() && *new_idx.name() == "original");
15416 if (!passed) {
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 }
second (pd_test_1_all.cpp:7534)
7524 std::cout << "========= second property =============================";
7525
7526 std::vector<std::optional<numpy::datetime64>> values = {
7527 make_dt(0), // Second 0
7528 make_dt(30 * NS_PER_SEC), // Second 30
7529 make_dt(59 * NS_PER_SEC) // Second 59
7530 };
7531 pandas::DatetimeArray arr(values);
7532 pandas::DatetimeIndex idx(arr);
7533
7534 auto seconds = idx.second();
7535
7536 bool passed = (seconds.size() == 3);
7537 auto s0 = seconds[0];
7538 auto s1 = seconds[1];
7539 auto s2 = seconds[2];
7540 passed = passed && s0.has_value() && *s0 == 0;
7541 passed = passed && s1.has_value() && *s1 == 30;
7542 passed = passed && s2.has_value() && *s2 == 59;
7543
7544 if (!passed) {
set_freq (pd_test_1_all.cpp:8254)
8244void pd_test_datetime_mixin_set_freq() {
8245 std::cout << "========= set_freq ====================================";
8246
8247 std::vector<std::optional<numpy::datetime64>> values = {
8248 numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond)
8249 };
8250 pandas::DatetimeArray arr(values);
8251 pandas::DatetimeMixinIndex idx(arr);
8252
8253 idx.set_freq("D");
8254 auto f = idx.freq();
8255
8256 bool passed = (f.has_value() && *f == "D");
8257 if (!passed) {
8258 std::cout << " [FAIL] : in pd_test_datetime_mixin_set_freq()" << std::endl;
8259 throw std::runtime_error("pd_test_datetime_mixin_set_freq failed");
8260 }
8261
8262 std::cout << " -> tests passed" << std::endl;
8263}
snap (pd_test_1_all.cpp:8364)
8354void pd_test_datetime_mixin_snap() {
8355 std::cout << "========= snap ========================================";
8356
8357 std::vector<std::optional<numpy::datetime64>> values = {
8358 numpy::datetime64(1000000000123456789LL, numpy::DateTimeUnit::Nanosecond)
8359 };
8360 pandas::DatetimeArray arr(values);
8361 pandas::DatetimeMixinIndex idx(arr);
8362
8363 pandas::DatetimeMixinIndex snapped = idx.snap("s");
8364
8365 bool passed = (snapped.size() == 1);
8366 if (!passed) {
8367 std::cout << " [FAIL] : in pd_test_datetime_mixin_snap()" << std::endl;
8368 throw std::runtime_error("pd_test_datetime_mixin_snap failed");
8369 }
8370
8371 std::cout << " -> tests passed" << std::endl;
8372}
strftime (pd_test_1_all.cpp:8434)
8424void pd_test_datetime_mixin_strftime() {
8425 std::cout << "========= strftime ====================================";
8426
8427 std::vector<std::optional<numpy::datetime64>> values = {
8428 numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond), // 1970-01-01
8429 numpy::datetime64(86400000000000LL, numpy::DateTimeUnit::Nanosecond) // 1970-01-02
8430 };
8431 pandas::DatetimeArray arr(values);
8432 pandas::DatetimeMixinIndex idx(arr);
8433
8434 std::vector<std::string> formatted = idx.strftime("%Y-%m-%d");
8435
8436 bool passed = (formatted.size() == 2 && !formatted[0].empty() && !formatted[1].empty());
8437 if (!passed) {
8438 std::cout << " [FAIL] : in pd_test_datetime_mixin_strftime()" << std::endl;
8439 throw std::runtime_error("pd_test_datetime_mixin_strftime failed");
8440 }
8441
8442 std::cout << " -> tests passed" << std::endl;
8443}
td_days (pd_test_1_all.cpp:8603)
8593void pd_test_timedelta_mixin_days() {
8594 std::cout << "========= days component (Timedelta) ==================";
8595
8596 std::vector<std::optional<numpy::timedelta64>> values = {
8597 numpy::timedelta64(172800000000000LL, numpy::DateTimeUnit::Nanosecond) // 2 days
8598 };
8599 pandas::TimedeltaArray arr(values);
8600 pandas::TimedeltaMixinIndex idx(arr);
8601
8602 pandas::IntegerArray<numpy::int64> days = idx.td_days();
8603
8604 bool passed = (days.size() == 1 && days[0].has_value() && *days[0] == 2);
8605 if (!passed) {
8606 int64_t got = days[0].has_value() ? *days[0] : -1;
8607 std::cout << " [FAIL] : in pd_test_timedelta_mixin_days() expected 2, got " << got << std::endl;
8608 throw std::runtime_error("pd_test_timedelta_mixin_days failed");
8609 }
8610
8611 std::cout << " -> tests passed" << std::endl;
8612}
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;
type_id (pd_test_3_all.cpp:25592)
25582// ------------------- pd_test_value_classify (end) ------------------
25583
25584// ------------------- pd_test_index_type_id (start) ------------------
25585namespace dataframe_tests_index_type_id {
25586
25587void pd_test_index_type_id_dispatch() {
25588 std::cout << "========= IndexTypeId dispatch =======================";
25589
25590 // RangeIndex
25591 ::pandas::RangeIndex ri(0, 5);
25592 if (ri.type_id() != ::pandas::IndexTypeId::RangeIndex)
25593 throw std::runtime_error("RangeIndex type_id failed");
25594
25595 // Index<string>
25596 ::pandas::Index<std::string> si(std::vector<std::string>{"a", "b", "c"});
25597 if (si.type_id() != ::pandas::IndexTypeId::IndexString)
25598 throw std::runtime_error("Index<string> type_id failed");
25599
25600 // Index<int64>
25601 ::pandas::Index<numpy::int64> ii(std::vector<numpy::int64>{1, 2, 3});
25602 if (ii.type_id() != ::pandas::IndexTypeId::IndexInt64)
tz (pd_test_2_all.cpp:17914)
17904 pandas::DataFrame df(data);
17905 df.set_index(std::make_unique<pandas::DatetimeIndex>(tz_aware_idx));
17906
17907 // Verify the index is timezone-aware
17908 const pandas::DatetimeIndex* original_idx = dynamic_cast<const pandas::DatetimeIndex*>(&df.index());
17909 if (!original_idx) {
17910 std::cout << " [FAIL] : in pd_test_tz_convert_basic() : index is not DatetimeIndex" << std::endl;
17911 throw std::runtime_error("pd_test_tz_convert_basic failed: index is not DatetimeIndex");
17912 }
17913
17914 std::string original_tz = original_idx->tz();
17915 if (original_tz.empty()) {
17916 std::cout << " [FAIL] : in pd_test_tz_convert_basic() : original index is not timezone-aware" << std::endl;
17917 throw std::runtime_error("pd_test_tz_convert_basic failed: original index is not timezone-aware");
17918 }
17919
17920 // Convert to Asia/Shanghai timezone
17921 pandas::DataFrame df_shanghai = df.tz_convert("Asia/Shanghai");
17922
17923 // Verify result has a DatetimeIndex
17924 const pandas::DatetimeIndex* converted_idx = dynamic_cast<const pandas::DatetimeIndex*>(&df_shanghai.index());
tz_aware (pd_test_1_all.cpp:8745)
8735 std::cout << "========= tz_localize =================================";
8736
8737 std::vector<std::optional<numpy::datetime64>> values = {
8738 numpy::datetime64(0LL, numpy::DateTimeUnit::Nanosecond)
8739 };
8740 pandas::DatetimeArray arr(values);
8741 pandas::DatetimeMixinIndex idx(arr);
8742
8743 pandas::DatetimeMixinIndex localized = idx.tz_localize("UTC");
8744
8745 bool passed = (localized.size() == 1 && localized.tz_aware());
8746 if (!passed) {
8747 std::cout << " [FAIL] : in pd_test_datetime_mixin_tz_localize()" << std::endl;
8748 throw std::runtime_error("pd_test_datetime_mixin_tz_localize failed");
8749 }
8750
8751 std::cout << " -> tests passed" << std::endl;
8752}
8753
8754// ============================================================================
8755// Conversion Method Tests
week (pd_test_timestamp_scalar.cpp:406)
396 // 2024-06-15 is a Saturday
397 pandas::Timestamp ts(2024, 6, 15);
398
399 if (ts.dayofweek() != 5) { pass = false; fail_msg = "2024-06-15 should be Saturday (5)"; }
400 if (ts.day_of_week() != 5) { pass = false; fail_msg = "day_of_week alias"; }
401 if (ts.dayofyear() != 167) { pass = false; fail_msg = "2024-06-15 should be day 167"; }
402 if (ts.day_of_year() != 167) { pass = false; fail_msg = "day_of_year alias"; }
403 if (ts.quarter() != 2) { pass = false; fail_msg = "June is Q2"; }
404 if (ts.days_in_month() != 30) { pass = false; fail_msg = "June has 30 days"; }
405
406 int week = ts.week();
407 if (week < 1 || week > 53) { pass = false; fail_msg = "week should be 1-53"; }
408
409 if (!pass) {
410 std::cout << " [FAIL] : in np_test_timestamp_derived() : " << fail_msg;
411 throw std::runtime_error("np_test_timestamp_derived failed: " + fail_msg);
412 }
413
414 std::cout << " -> tests passed" << std::endl;
415 }
weekday (pd_test_3_all.cpp:1471)
1461 std::cout << " [FAIL] date_range 10-arg form: expected size 10, got "
1462 << idx.size() << std::endl;
1463 throw std::runtime_error("date_range 10-arg form regressed");
1464 }
1465 }
1466
1467 std::cout << " -> tests passed" << std::endl;
1468}
1469
1470void pd_test_3_all_period_weekday() {
1471 std::cout << "========= PeriodArray.weekday() ======================";
1472
1473 // Create a PeriodArray with some dates
1474 std::vector<std::optional<numpy::int64>> ordinals = {0, 1, 2, 3, 4}; // Days from epoch
1475 pandas::PeriodArray arr(ordinals, "D");
1476
1477 pandas::IntegerArray<numpy::int32> weekdays = arr.weekday();
1478
1479 if (weekdays.size() != 5) {
1480 std::cout << " [FAIL] : in pd_test_3_all_period_weekday() : size should be 5" << std::endl;
1481 throw std::runtime_error("pd_test_3_all_period_weekday failed: size");
year (pd_test_1_all.cpp:1147)
1137 void pd_test_datetime_array_component_year() {
1138 std::cout << "========= DatetimeArray: year component ======================= ";
1139
1140 pandas::DatetimeArray arr(std::vector<std::string>{
1141 "2020-01-15",
1142 "NaT",
1143 "2025-06-20"
1144 });
1145
1146 auto years = arr.year();
1147
1148 auto y0 = years[0];
1149 if (!y0.has_value() || y0.value() != 2020) {
1150 std::cout << " [FAIL] : year[0] should be 2020" << std::endl;
1151 throw std::runtime_error("pd_test_datetime_array_component_year failed: year[0]");
1152 }
1153
1154 auto y1 = years[1];
1155 if (y1.has_value()) {
1156 std::cout << " [FAIL] : year[1] should be NA (NaT)" << std::endl;