Grouper#
-
class pandas::Grouper#
pandas C++ class.
Example#
#include <pandas/pandas.h>
using namespace pandas;
// Use Grouper
Grouper obj;
// ... operations ...
Constructors#
Signature |
Location |
Example |
|---|---|---|
|
pd_grouper.h:32 |
|
|
pd_grouper.h:35 |
|
|
pd_grouper.h:39 |
Construction#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
static Grouper |
pd_grouper.h:88 |
Data Manipulation#
Comparison#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
std::optional<std::variant<int, std::string>> |
pd_grouper.h:57 |
Type Checking#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
bool |
pd_grouper.h:69 |
Other Methods#
Signature |
Return Type |
Location |
Example |
|---|---|---|---|
|
int |
pd_grouper.h:59 |
|
|
std::optional<std::string> |
pd_grouper.h:61 |
|
|
std::optional<std::string> |
pd_grouper.h:63 |
|
|
std::optional<std::string> |
pd_grouper.h:58 |
|
|
static Grouper |
pd_grouper.h:79 |
|
|
std::optional<std::string> |
pd_grouper.h:56 |
|
|
std::optional<std::string> |
pd_grouper.h:62 |
|
|
std::optional<std::string> |
pd_grouper.h:65 |
|
|
std::string |
pd_grouper.h:64 |
|
|
Grouper& |
pd_grouper.h:101 |
|
|
Grouper& |
pd_grouper.h:103 |
|
|
Grouper& |
pd_grouper.h:106 |
|
|
Grouper& |
pd_grouper.h:98 |
|
|
Grouper& |
pd_grouper.h:95 |
|
|
Grouper& |
pd_grouper.h:102 |
|
|
Grouper& |
pd_grouper.h:96 |
|
|
Grouper& |
pd_grouper.h:97 |
|
|
Grouper& |
pd_grouper.h:105 |
|
|
Grouper& |
pd_grouper.h:104 |
|
|
Grouper& |
pd_grouper.h:100 |
|
|
bool |
pd_grouper.h:60 |
Code Examples#
The following examples are extracted from the test suite.
Grouper (pd_test_4_all.cpp:5041)
5031 "0 True 1.1 10.0 1.0 x\n"
5032 "1 False 2.2 20.0 2.0 y\n"
5033 "2 True 3.3 30.0 3.0 z\n"
5034 "3 NaN NaN NaN NaN NaN\n"
5035 "4 NaN NaN NaN NaN NaN";
5036
5037 check_str("reindex_types_default_nan", expected, re.to_string());
5038}
5039
5040// ============================================================================
5041// Group C — `__freq_idx__` synthetic name leak in groupby(Grouper(freq=...))
5042// Source: pandasPython_tests/test_anal_grouper_freq_level_compare_full.py
5043//
5044// All 7 cases share the same shape: DatetimeIndex (quarter-end) + 2 int
5045// columns. PandasCore's groupby leaves the synthetic index name
5046// "__freq_idx__" on the result, and the formatter dutifully prints it.
5047// pandas hides this entirely. We reproduce by constructing the *result*
5048// DataFrame directly with the leaky index name — fix paths: either groupby
5049// must clear the name, or the formatter must blacklist names beginning with
5050// "__freq_idx__" / leading underscores from synthetic groupers.
5051// ============================================================================
Grouper (pd_test_4_all.cpp:5041)
5031 "0 True 1.1 10.0 1.0 x\n"
5032 "1 False 2.2 20.0 2.0 y\n"
5033 "2 True 3.3 30.0 3.0 z\n"
5034 "3 NaN NaN NaN NaN NaN\n"
5035 "4 NaN NaN NaN NaN NaN";
5036
5037 check_str("reindex_types_default_nan", expected, re.to_string());
5038}
5039
5040// ============================================================================
5041// Group C — `__freq_idx__` synthetic name leak in groupby(Grouper(freq=...))
5042// Source: pandasPython_tests/test_anal_grouper_freq_level_compare_full.py
5043//
5044// All 7 cases share the same shape: DatetimeIndex (quarter-end) + 2 int
5045// columns. PandasCore's groupby leaves the synthetic index name
5046// "__freq_idx__" on the result, and the formatter dutifully prints it.
5047// pandas hides this entirely. We reproduce by constructing the *result*
5048// DataFrame directly with the leaky index name — fix paths: either groupby
5049// must clear the name, or the formatter must blacklist names beginning with
5050// "__freq_idx__" / leading underscores from synthetic groupers.
5051// ============================================================================
Grouper (pd_test_4_all.cpp:5041)
5031 "0 True 1.1 10.0 1.0 x\n"
5032 "1 False 2.2 20.0 2.0 y\n"
5033 "2 True 3.3 30.0 3.0 z\n"
5034 "3 NaN NaN NaN NaN NaN\n"
5035 "4 NaN NaN NaN NaN NaN";
5036
5037 check_str("reindex_types_default_nan", expected, re.to_string());
5038}
5039
5040// ============================================================================
5041// Group C — `__freq_idx__` synthetic name leak in groupby(Grouper(freq=...))
5042// Source: pandasPython_tests/test_anal_grouper_freq_level_compare_full.py
5043//
5044// All 7 cases share the same shape: DatetimeIndex (quarter-end) + 2 int
5045// columns. PandasCore's groupby leaves the synthetic index name
5046// "__freq_idx__" on the result, and the formatter dutifully prints it.
5047// pandas hides this entirely. We reproduce by constructing the *result*
5048// DataFrame directly with the leaky index name — fix paths: either groupby
5049// must clear the name, or the formatter must blacklist names beginning with
5050// "__freq_idx__" / leading underscores from synthetic groupers.
5051// ============================================================================
from_freq (pd_test_5_all.cpp:352)
342 int local_fail = 0;
343 // 12 monthly dates starting 2020-01-01
344 pandas::DatetimeIndex dt_idx("2020-01-01", 12, "ME");
345 pandas::DataFrame df;
346 df.set_index(dt_idx);
347 std::vector<int64_t> amounts = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200};
348 std::vector<int64_t> counts(12, 1);
349 df.add_column<int64_t>("Amount", amounts);
350 df.add_column<int64_t>("Count", counts);
351
352 auto result = df.groupby(pandas::Grouper::from_freq("QE")).sum();
353
354 std::string expected =
355 " Amount Count\n"
356 "2020-03-31 600 3\n"
357 "2020-06-30 1500 3\n"
358 "2020-09-30 2400 3\n"
359 "2020-12-31 3300 3";
360 pandas_tests::check(result.to_string() == expected, "grouper_freq_dtindex.str", local_fail);
361 if (local_fail > 0) {
362 std::cout << " [FAIL] : in f_test_anal_grouper_freq_level_compare_full_175() : " << local_fail << " checks failed" << std::endl;
dropna (pd_test_1_all.cpp:531)
521 }
522
523 // Test isna array
524 numpy::NDArray<numpy::bool_> na_mask = arr.isna();
525 if (na_mask.getSize() != 4) {
526 std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : isna size != 4" << std::endl;
527 throw std::runtime_error("pd_test_categorical_array_na_handling failed: isna size != 4");
528 }
529
530 // Test dropna
531 pandas::CategoricalArray dropped = arr.dropna();
532 if (dropped.size() != 2) {
533 std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : dropna size != 2" << std::endl;
534 throw std::runtime_error("pd_test_categorical_array_na_handling failed: dropna size != 2");
535 }
536
537 // Test fillna (fill with existing category)
538 pandas::CategoricalArray filled = arr.fillna("a"); // 'a' is in categories
539 if (filled.has_na()) {
540 std::cout << " [FAIL] : in pd_test_categorical_array_na_handling() : fillna should have no NA" << std::endl;
541 throw std::runtime_error("pd_test_categorical_array_na_handling failed: fillna should have no NA");
set_axis (pd_test_1_all.cpp:6673)
6663 std::cout << " -> tests passed" << std::endl;
6664 }
6665
6666 // =====================================================================
6667 // Test: Index Operations
6668 // =====================================================================
6669 void pd_test_dataframe_index_ops() {
6670 std::cout << "========= index operations =================";
6671
6672 // Test set_axis (rows)
6673 {
6674 std::map<std::string, std::vector<int>> data;
6675 data["A"] = {1, 2, 3};
6676 pandas::DataFrame df(data);
6677
6678 auto renamed = df.set_axis({"x", "y", "z"}, 0);
6679 std::string idx0 = renamed.index().get_value_str(0);
6680 if (idx0 != "x") {
6681 std::cout << " [FAIL] : in pd_test_dataframe_index_ops() : set_axis first label should be 'x'" << std::endl;
6682 throw std::runtime_error("pd_test_dataframe_index_ops failed: set_axis");
level (pd_test_2_all.cpp:10027)
10017 std::cout << " [FAIL] : in pd_test_swaplevel_negative_indices() : wrong index values" << std::endl;
10018 std::cout << " Expected: C:B:A, F:E:D" << std::endl;
10019 std::cout << " Got: " << idx0 << ", " << idx1 << std::endl;
10020 throw std::runtime_error("pd_test_swaplevel_negative_indices failed");
10021 }
10022
10023 std::cout << " -> tests passed" << std::endl;
10024 }
10025
10026 void pd_test_swaplevel_same_level() {
10027 std::cout << "========= swaplevel same level (no change) =============";
10028
10029 std::map<std::string, std::vector<std::string>> data = {
10030 {"value", {"a", "b"}}
10031 };
10032
10033 pandas::DataFrame df(data);
10034
10035 std::vector<std::string> hier_index = {"X:Y:Z", "A:B:C"};
10036 df.set_index(std::make_unique<pandas::Index<std::string>>(hier_index));
is_time_grouper (pd_test_3_all.cpp:19042)
19032 throw std::runtime_error("pd_test_grouper_builder: freq failed");
19033 }
19034 if (g.sort()) {
19035 std::cout << " [FAIL] : builder sort failed" << std::endl;
19036 throw std::runtime_error("pd_test_grouper_builder: sort failed");
19037 }
19038 if (g.dropna()) {
19039 std::cout << " [FAIL] : builder dropna failed" << std::endl;
19040 throw std::runtime_error("pd_test_grouper_builder: dropna failed");
19041 }
19042 if (!g.is_time_grouper()) {
19043 std::cout << " [FAIL] : is_time_grouper failed" << std::endl;
19044 throw std::runtime_error("pd_test_grouper_builder: is_time_grouper failed");
19045 }
19046
19047 std::cout << " -> tests passed" << std::endl;
19048}
19049
19050// ============================================================================
19051// Test Grouper full constructor
19052// ============================================================================
axis (pd_test_1_all.cpp:25083)
25073 }
25074
25075 if (!passed) {
25076 throw std::runtime_error("pd_test_median_empty_column failed");
25077 }
25078
25079 std::cout << " -> tests passed" << std::endl;
25080 }
25081
25082 void pd_test_median_invalid_axis() {
25083 std::cout << "========= median invalid axis (throws exception) =================";
25084
25085 std::map<std::string, std::vector<numpy::float64>> data;
25086 data["A"] = {1.0, 2.0, 3.0};
25087
25088 pandas::DataFrame df(data);
25089
25090 bool passed = false;
25091 try {
25092 df.median(2); // Invalid axis
25093 } catch (const std::exception&) {
closed (pd_test_1_all.cpp:1903)
1893// ============================================================================
1894void test_constructors() {
1895 std::cout << "========= IntervalArray: constructors ======================= ";
1896
1897 // Default constructor
1898 pandas::IntervalArrayFloat64 empty;
1899 if (empty.size() != 0) {
1900 std::cout << "[FAIL] : in test_constructors() : default constructor size" << std::endl;
1901 return;
1902 }
1903 if (empty.closed() != pandas::IntervalClosed::Right) {
1904 std::cout << "[FAIL] : in test_constructors() : default closure" << std::endl;
1905 return;
1906 }
1907
1908 // Constructor from left/right arrays
1909 numpy::NDArray<numpy::float64> left(std::vector<size_t>{3});
1910 numpy::NDArray<numpy::float64> right(std::vector<size_t>{3});
1911 left.setElementAt({0}, 0.0); right.setElementAt({0}, 1.0);
1912 left.setElementAt({1}, 1.0); right.setElementAt({1}, 2.0);
1913 left.setElementAt({2}, 2.0); right.setElementAt({2}, 3.0);
convention (pd_test_5_all.cpp:67797)
67787 std::cout << "-- case_30_agg_var_passlock\n";
67788 auto s = make_carrier({1.0, 2.0, 3.0}, "UInt8");
67789 auto v = s.agg("var");
67790 pandas_tests::check(opt_equals(v, 1.0, "case_30.agg_var_value"),
67791 "case_30.agg_var_eq_1", local_fail);
67792}
67793
67794void f_series_uint_sum_agg_typed_9_4791556_case_31_empty_uint8_sum_value(int& local_fail) {
67795 std::cout << "-- case_31_empty_uint8_sum_value\n";
67796 // empty UInt8: sum() returns optional<double>(0.0) per pandas
67797 // convention (identity element). Binding stamps uint32(0).
67798 auto s = make_carrier({}, "UInt8");
67799 auto v = s.sum();
67800 pandas_tests::check(opt_equals(v, 0.0, "case_31.empty_sum_value"),
67801 "case_31.empty_sum_eq_0", local_fail);
67802}
67803
67804void f_series_uint_sum_agg_typed_9_4791556_case_32_empty_uint8_prod_value(int& local_fail) {
67805 std::cout << "-- case_32_empty_uint8_prod_value\n";
67806 // empty UInt8 prod -> 1 (multiplicative identity). Binding stamps
67807 // uint32(1).
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}
freq_key (pd_test_3_all.cpp:11083)
11073void pd_test_3_all_groupby_mixed() {
11074 std::cout << "========= groupby(mixed Grouper+string) ================";
11075 pandas::DataFrame df;
11076 df.add_column<std::string>("Buyer", {"Alice","Bob","Alice","Bob"});
11077 df.add_column<double>("Amount", {100.0, 200.0, 150.0, 250.0});
11078 auto dates = pandas::date_range("2024-01-15", 4, "15D");
11079 df.set_index(std::make_shared<pandas::DatetimeIndex>(dates));
11080 df.add_column<std::string>("Date_str", {"2024-01-15","2024-01-30","2024-02-14","2024-03-01"});
11081 auto result = df.groupby(
11082 {pandas::Grouper::freq_key("1ME", "Date_str"), std::string("Buyer")}).sum();
11083 if (result.nrows() < 2) {
11084 std::cout << " [FAIL] : in pd_test_3_all_groupby_mixed()" << std::endl;
11085 throw std::runtime_error("groupby mixed failed");
11086 }
11087 std::cout << " -> tests passed" << std::endl;
11088}
11089
11090void pd_test_3_all_ndframebase_unstack() {
11091 std::cout << "========= NDFrameBase.unstack() ========================";
11092 auto mi = pandas::MultiIndex::from_arrays<std::string>(
key (pd_test_2_all.cpp:11898)
11888 if (!threw) {
11889 std::cout << " [FAIL] : should have thrown" << std::endl;
11890 throw std::runtime_error("pd_test_to_hdf_invalid_mode failed");
11891 }
11892
11893 std::cout << " -> tests passed" << std::endl;
11894 }
11895
11896 void pd_test_to_hdf_empty_key() {
11897 std::cout << "========= to_hdf empty key (real HDF5) =========================";
11898
11899 std::map<std::string, std::vector<double>> data = {{"col", {1.0, 2.0, 3.0}}};
11900 pandas::DataFrame df(data);
11901
11902 bool threw = false;
11903 try {
11904 df.to_hdf("temp/test.h5", "");
11905 } catch (const std::exception& e) {
11906 threw = true;
11907 std::string msg = e.what();
label (pd_test_4_all.cpp:4935)
4925// Helper: compare and report
4926// ----------------------------------------------------------------------------
4927static void check_str(const std::string& label,
4928 const std::string& expected,
4929 const std::string& actual) {
4930 int _f = 0;
4931 pandas_tests::check_str_ws(label, expected, actual, _f);
4932 if (_f > 0) throw std::runtime_error(label + ": str mismatch");
4933}
4934
4935// Slugify a python compare-test label ("a.b.c" → "a_b_c") matching the
4936// scheme in scripts/gen_repr_mismatch_fixtures.py.
4937static std::string slugify_label(const std::string& label) {
4938 std::string out = label;
4939 for (char& ch : out) {
4940 if (ch == '.') ch = '_';
4941 }
4942 return out;
4943}
4944
4945// Load a captured pandas-generated expected output file. The file is written
offset (pd_test_3_all.cpp:18224)
18214namespace dataframe_tests {
18215namespace dataframe_tests_dateoffset {
18216
18217// ============================================================================
18218// Test Day offset
18219// ============================================================================
18220
18221void pd_test_day_offset() {
18222 std::cout << "========= Day offset ===================================";
18223
18224 pandas::Day offset(5);
18225 if (offset.n() != 5) {
18226 std::cout << " [FAIL] : Day n() failed" << std::endl;
18227 throw std::runtime_error("pd_test_day_offset: n() failed");
18228 }
18229 if (offset.freqstr() != "D") {
18230 std::cout << " [FAIL] : Day freqstr() failed" << std::endl;
18231 throw std::runtime_error("pd_test_day_offset: freqstr() failed");
18232 }
18233 if (offset.name() != "Day") {
18234 std::cout << " [FAIL] : Day name() failed" << std::endl;
origin (pd_test_2_all.cpp:22665)
22655 pandas::Timestamp ts(v->getValue());
22656 check(ts.year() == 1970, "year==1970");
22657 check(ts.month() == 1, "month==1");
22658 check(ts.day() == 2, "day==2");
22659 }
22660}
22661
22662void test_to_datetime_numeric_origin() {
22663 std::cout << " -- test_to_datetime_numeric_origin --" << std::endl;
22664 // origin = 2000-01-01, values = [1, 2, 3] days
22665 pandas::Timestamp origin(2000, 1, 1, 0, 0, 0, 0, 0, "");
22666 int64_t origin_ns = origin.value();
22667 std::vector<double> vals = {1.0, 2.0, 3.0};
22668 auto arr = pandas::to_datetime_numeric(vals, "D", origin_ns);
22669 check(arr.size() == 3, "size==3");
22670
22671 // Day 1 from 2000-01-01 = 2000-01-02
22672 auto v0 = arr[0];
22673 check(v0.has_value(), "v0_has_value");
22674 if (v0.has_value()) {
22675 pandas::Timestamp ts(v0->getValue());
set_closed (pd_test_1_all.cpp:2285)
2275 std::vector<numpy::float64> breaks = {0.0, 1.0, 2.0};
2276 auto arr = pandas::IntervalArrayFloat64::from_breaks(breaks, pandas::IntervalClosed::Right);
2277
2278 if (arr.closed() != pandas::IntervalClosed::Right) {
2279 std::cout << "[FAIL] : in test_set_closed() : initial closure" << std::endl;
2280 return;
2281 }
2282
2283 // Change to left-closed
2284 auto arr_left = arr.set_closed(pandas::IntervalClosed::Left);
2285 if (arr_left.closed() != pandas::IntervalClosed::Left) {
2286 std::cout << "[FAIL] : in test_set_closed() : set to Left" << std::endl;
2287 return;
2288 }
2289
2290 // Original should be unchanged
2291 if (arr.closed() != pandas::IntervalClosed::Right) {
2292 std::cout << "[FAIL] : in test_set_closed() : original changed" << std::endl;
2293 return;
2294 }
set_dropna (pd_test_3_all.cpp:19024)
19014}
19015
19016// ============================================================================
19017// Test Grouper builder pattern
19018// ============================================================================
19019
19020void pd_test_grouper_builder() {
19021 std::cout << "========= Grouper: builder pattern =========================";
19022
19023 pandas::Grouper g;
19024 g.set_key("A").set_freq("M").set_sort(false).set_dropna(false);
19025
19026 if (g.key().value() != "A") {
19027 std::cout << " [FAIL] : builder key failed" << std::endl;
19028 throw std::runtime_error("pd_test_grouper_builder: key failed");
19029 }
19030 if (g.freq().value() != "M") {
19031 std::cout << " [FAIL] : builder freq failed" << std::endl;
19032 throw std::runtime_error("pd_test_grouper_builder: freq failed");
19033 }
19034 if (g.sort()) {
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}
set_key (pd_test_3_all.cpp:19024)
19014}
19015
19016// ============================================================================
19017// Test Grouper builder pattern
19018// ============================================================================
19019
19020void pd_test_grouper_builder() {
19021 std::cout << "========= Grouper: builder pattern =========================";
19022
19023 pandas::Grouper g;
19024 g.set_key("A").set_freq("M").set_sort(false).set_dropna(false);
19025
19026 if (g.key().value() != "A") {
19027 std::cout << " [FAIL] : builder key failed" << std::endl;
19028 throw std::runtime_error("pd_test_grouper_builder: key failed");
19029 }
19030 if (g.freq().value() != "M") {
19031 std::cout << " [FAIL] : builder freq failed" << std::endl;
19032 throw std::runtime_error("pd_test_grouper_builder: freq failed");
19033 }
19034 if (g.sort()) {
set_level (pd_test_5_all.cpp:21141)
21131 "case7.index_name_is_date"),
21132 "case7.index_name_is_date", local_fail);
21133 pandas_tests::check(str_eq(result.to_string(), expected, "case7.to_string"),
21134 "case7.to_string_matches_pandas", local_fail);
21135}
21136
21137void f_grouper_freq_key_col_index_name_742013_case_8_named_dtindex_level0_QE(int& local_fail) {
21138 std::cout << "-- f_grouper_freq_key_col_index_name_742013_case_8_named_dtindex_level0_QE\n";
21139 auto df = make_df_named_dtindex_as_index();
21140 pandas::Grouper g;
21141 g.set_level(0).set_freq("QE");
21142 auto result = df.groupby(g).sum();
21143
21144 std::string expected =
21145 " Amount Count\n"
21146 "dtidx \n"
21147 "2020-03-31 600 3\n"
21148 "2020-06-30 1500 3\n"
21149 "2020-09-30 2400 3\n"
21150 "2020-12-31 3300 3";
21151 pandas_tests::check(opt_eq(result.index_name(), std::optional<std::string>("dtidx"),
set_level (pd_test_5_all.cpp:21141)
21131 "case7.index_name_is_date"),
21132 "case7.index_name_is_date", local_fail);
21133 pandas_tests::check(str_eq(result.to_string(), expected, "case7.to_string"),
21134 "case7.to_string_matches_pandas", local_fail);
21135}
21136
21137void f_grouper_freq_key_col_index_name_742013_case_8_named_dtindex_level0_QE(int& local_fail) {
21138 std::cout << "-- f_grouper_freq_key_col_index_name_742013_case_8_named_dtindex_level0_QE\n";
21139 auto df = make_df_named_dtindex_as_index();
21140 pandas::Grouper g;
21141 g.set_level(0).set_freq("QE");
21142 auto result = df.groupby(g).sum();
21143
21144 std::string expected =
21145 " Amount Count\n"
21146 "dtidx \n"
21147 "2020-03-31 600 3\n"
21148 "2020-06-30 1500 3\n"
21149 "2020-09-30 2400 3\n"
21150 "2020-12-31 3300 3";
21151 pandas_tests::check(opt_eq(result.index_name(), std::optional<std::string>("dtidx"),
set_sort (pd_test_3_all.cpp:19024)
19014}
19015
19016// ============================================================================
19017// Test Grouper builder pattern
19018// ============================================================================
19019
19020void pd_test_grouper_builder() {
19021 std::cout << "========= Grouper: builder pattern =========================";
19022
19023 pandas::Grouper g;
19024 g.set_key("A").set_freq("M").set_sort(false).set_dropna(false);
19025
19026 if (g.key().value() != "A") {
19027 std::cout << " [FAIL] : builder key failed" << std::endl;
19028 throw std::runtime_error("pd_test_grouper_builder: key failed");
19029 }
19030 if (g.freq().value() != "M") {
19031 std::cout << " [FAIL] : builder freq failed" << std::endl;
19032 throw std::runtime_error("pd_test_grouper_builder: freq failed");
19033 }
19034 if (g.sort()) {
sort (pd_test_3_all.cpp:3869)
3859 throw std::runtime_error("last 2 positions should be NaN");
3860 }
3861 if (std::abs(result[0] - 3.0) > 0.001) {
3862 throw std::runtime_error("shift(-2) [0] should be 3.0");
3863 }
3864
3865 std::cout << " -> tests passed" << std::endl;
3866}
3867
3868void pd_test_3_all_index_sort() {
3869 std::cout << "========= Index.sort() =============================";
3870
3871 pandas::Index<numpy::int64> idx({3, 1, 4, 1, 5, 9, 2, 6});
3872 auto result = idx.sort();
3873
3874 if (result[0] != 1 || result[1] != 1 || result[7] != 9) {
3875 throw std::runtime_error("sort() not working correctly");
3876 }
3877
3878 // Test descending
3879 result = idx.sort(false);