Interval#

class pandas::Interval#

Scalar type representing a single value.

Example#

#include <pandas/pandas.h>
using namespace pandas;

// Use Interval
Interval obj;
// ... operations ...

Constructors#

Signature

Location

Example

Interval(T left, T right, const std::string& closed)

pd_interval_dtype.h:292

View

Arithmetic#

Signature

Return Type

Location

Example

const std::string& subtype_override() const

const std::string&

pd_interval_dtype.h:254

View

Comparison#

Signature

Return Type

Location

Example

T left() const

T

pd_interval_dtype.h:303

View

T length() const

T

pd_interval_dtype.h:320

View

I/O#

Signature

Return Type

Location

Example

std::string to_string() const

std::string

pd_interval_dtype.h:485

View

Type Checking#

Signature

Return Type

Location

Example

bool is_empty() const

bool

pd_interval_dtype.h:357

View

Other Methods#

Signature

Return Type

Location

Example

IntervalClosed closed() const

IntervalClosed

pd_interval_dtype.h:327

View

bool closed_left() const

bool

pd_interval_dtype.h:339

bool closed_right() const

bool

pd_interval_dtype.h:346

std::string closed_string() const

std::string

pd_interval_dtype.h:332

View

bool contains(T value) const

bool

pd_interval_dtype.h:373

View

size_t hash() const

size_t

pd_interval_dtype.h:570

double mid() const

double

pd_interval_dtype.h:313

View

bool overlaps(const Interval& other) const

bool

pd_interval_dtype.h:396

View

std::string repr() const

std::string

pd_interval_dtype.h:524

View

T right() const

T

pd_interval_dtype.h:308

View

void set_subtype_override(const std::string& s)

void

pd_interval_dtype.h:252

View

Code Examples#

The following examples are extracted from the test suite.

Interval (pd_test_3_all.cpp:24961)
24951    return dataframe_tests_interval_type_inference::pd_test_interval_type_inference_main();
24952}
24953// ------------------- pd_test_interval_type_inference (end) ---------------------------
24954
24955// ------------------- pd_test_interval_repr (start) ---------------------------
24956namespace dataframe_tests_interval_repr {
24957
24958void pd_test_interval_repr_integer() {
24959    std::cout << "========= Interval repr integer bounds =================";
24960    pandas::Interval<double> iv(0.0, 5.0);
24961    if (iv.repr() != "Interval(0, 5, closed='right')")
24962        throw std::runtime_error("repr mismatch: " + iv.repr());
24963    std::cout << " -> tests passed" << std::endl;
24964}
24965
24966void pd_test_interval_repr_float() {
24967    std::cout << "========= Interval repr float bounds ====================";
24968    pandas::Interval<double> iv(0.0, 1.5);
24969    if (iv.repr() != "Interval(0.0, 1.5, closed='right')")
24970        throw std::runtime_error("repr mismatch: " + iv.repr());
24971    std::cout << " -> tests passed" << std::endl;
subtype_override (pd_test_3_all.cpp:24889)
24879    return dataframe_tests_bdate_timedelta_range::pd_test_bdate_timedelta_range_main();
24880}
24881// ------------------- pd_test_bdate_timedelta_range (end) ---------------------------
24882
24883// ------------------- pd_test_interval_type_inference (begin) ---------------------------
24884namespace dataframe_tests_interval_type_inference {
24885
24886void pd_test_interval_type_inference_breaks_int() {
24887    std::cout << "========= interval_type_inference_breaks_int ======================= ";
24888    auto idx = pandas::IntervalIndex<double>::from_breaks({0.0, 1.0, 2.0, 3.0});
24889    if (idx.subtype_override() != "int64")
24890        throw std::runtime_error("expected subtype_override 'int64', got '" + idx.subtype_override() + "'");
24891    std::string dtype = idx.dtype_name();
24892    if (dtype.find("int64") == std::string::npos)
24893        throw std::runtime_error("expected dtype containing 'int64', got '" + dtype + "'");
24894    std::string fmt = idx.format_interval(0);
24895    if (fmt.find('.') != std::string::npos)
24896        throw std::runtime_error("expected integer format without decimal, got '" + fmt + "'");
24897    std::cout << " -> tests passed" << std::endl;
24898}
left (pd_test_1_all.cpp:1909)
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);
1914
1915    pandas::IntervalArrayFloat64 arr1(left, right);
1916    if (arr1.size() != 3) {
1917        std::cout << "[FAIL] : in test_constructors() : array size" << std::endl;
1918        return;
1919    }
length (pd_test_1_all.cpp:2137)
2127    auto mid0 = mid_arr[0];
2128    auto mid1 = mid_arr[1];
2129    auto mid2 = mid_arr[2];
2130    if (!mid0.has_value() || std::abs(mid0.value() - 1.0) > 1e-10 ||
2131        !mid1.has_value() || std::abs(mid1.value() - 3.5) > 1e-10 ||
2132        !mid2.has_value() || std::abs(mid2.value() - 7.5) > 1e-10) {
2133        std::cout << "[FAIL] : in test_left_right_mid_length() : mid()" << std::endl;
2134        return;
2135    }
2136
2137    // Test length()
2138    auto len_arr = arr.length();
2139    if (len_arr.getElementAt({0}) != 2.0 ||
2140        len_arr.getElementAt({1}) != 3.0 ||
2141        len_arr.getElementAt({2}) != 5.0) {
2142        std::cout << "[FAIL] : in test_left_right_mid_length() : length()" << std::endl;
2143        return;
2144    }
2145
2146    std::cout << "-> tests passed" << std::endl;
2147}
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];
is_empty (pd_test_1_all.cpp:2164)
2154    // Test with right-closed intervals (a, b]
2155    std::vector<std::pair<numpy::float64, numpy::float64>> tuples = {
2156        {0.0, 1.0},   // Not empty
2157        {1.0, 1.0},   // Empty (1, 1] has no points
2158        {2.0, 2.0},   // Empty
2159        {2.0, 3.0}    // Not empty
2160    };
2161
2162    auto arr_right = pandas::IntervalArrayFloat64::from_tuples(tuples, pandas::IntervalClosed::Right);
2163    auto empty_right = arr_right.is_empty();
2164
2165    if (empty_right[0].value_or(true) != false ||
2166        empty_right[1].value_or(false) != true ||
2167        empty_right[2].value_or(false) != true ||
2168        empty_right[3].value_or(true) != false) {
2169        std::cout << "[FAIL] : in test_is_empty() : right-closed" << std::endl;
2170        return;
2171    }
2172
2173    // Test with both-closed intervals [a, b] - [1, 1] is NOT empty
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);
closed_string (pd_test_1_all.cpp:12813)
12803    std::cout << " -> tests passed" << std::endl;
12804}
12805
12806void pd_test_interval_index_closed_string() {
12807    std::cout << "========= closed_string =========================";
12808
12809    auto idx_right = pandas::IntervalIndex64::from_breaks({0, 1, 2}, pandas::IntervalClosed::Right);
12810    auto idx_left = pandas::IntervalIndex64::from_breaks({0, 1, 2}, pandas::IntervalClosed::Left);
12811
12812    bool passed = (idx_right.closed_string() == "right" && idx_left.closed_string() == "left");
12813    if (!passed) {
12814        std::cout << "  [FAIL] : in pd_test_interval_index_closed_string() : closed_string check failed" << std::endl;
12815        throw std::runtime_error("pd_test_interval_index_closed_string failed");
12816    }
12817
12818    std::cout << " -> tests passed" << std::endl;
12819}
12820
12821void pd_test_interval_index_is_left_right_closed() {
12822    std::cout << "========= is_left_closed/is_right_closed =========================";
contains (pd_test_1_all.cpp:2200)
2190// Test: contains method
2191// ============================================================================
2192void test_contains() {
2193    std::cout << "========= IntervalArray: contains ======================= ";
2194
2195    std::vector<numpy::float64> breaks = {0.0, 1.0, 2.0, 3.0};
2196
2197    // Right-closed intervals: (0, 1], (1, 2], (2, 3]
2198    auto arr_right = pandas::IntervalArrayFloat64::from_breaks(breaks, pandas::IntervalClosed::Right);
2199
2200    // Test contains(1.0) - should be in interval 0 but not 1 (since 1 is exclusive on left of interval 1)
2201    auto contains_1 = arr_right.contains(1.0);
2202    // (0, 1] contains 1: yes, (1, 2] contains 1: no (open on left), (2, 3] contains 1: no
2203    if (contains_1[0].value_or(false) != true ||
2204        contains_1[1].value_or(true) != false ||
2205        contains_1[2].value_or(true) != false) {
2206        std::cout << "[FAIL] : in test_contains() : right-closed contains 1.0" << std::endl;
2207        return;
2208    }
2209
2210    // Left-closed intervals: [0, 1), [1, 2), [2, 3)
mid (pd_test_1_all.cpp:2124)
2114    // Test right()
2115    auto right_arr = arr.right();
2116    if (right_arr.getElementAt({0}) != 2.0 ||
2117        right_arr.getElementAt({1}) != 5.0 ||
2118        right_arr.getElementAt({2}) != 10.0) {
2119        std::cout << "[FAIL] : in test_left_right_mid_length() : right()" << std::endl;
2120        return;
2121    }
2122
2123    // Test mid()
2124    auto mid_arr = arr.mid();
2125    // (0+2)/2=1, (2+5)/2=3.5, (5+10)/2=7.5
2126    auto mid0 = mid_arr[0];
2127    auto mid1 = mid_arr[1];
2128    auto mid2 = mid_arr[2];
2129    if (!mid0.has_value() || std::abs(mid0.value() - 1.0) > 1e-10 ||
2130        !mid1.has_value() || std::abs(mid1.value() - 3.5) > 1e-10 ||
2131        !mid2.has_value() || std::abs(mid2.value() - 7.5) > 1e-10) {
2132        std::cout << "[FAIL] : in test_left_right_mid_length() : mid()" << std::endl;
2133        return;
overlaps (pd_test_1_all.cpp:2244)
2234// Test: overlaps method
2235// ============================================================================
2236void test_overlaps() {
2237    std::cout << "========= IntervalArray: overlaps ======================= ";
2238
2239    std::vector<numpy::float64> breaks = {0.0, 2.0, 4.0, 6.0};
2240    // Right-closed: (0, 2], (2, 4], (4, 6]
2241    auto arr = pandas::IntervalArrayFloat64::from_breaks(breaks, pandas::IntervalClosed::Right);
2242
2243    // Check overlap with (1, 3]
2244    auto overlap_1_3 = arr.overlaps(1.0, 3.0);
2245    // (0, 2] overlaps (1, 3]? Yes (share 1-2)
2246    // (2, 4] overlaps (1, 3]? Yes (share 2-3)
2247    // (4, 6] overlaps (1, 3]? No
2248    if (overlap_1_3[0].value_or(false) != true ||
2249        overlap_1_3[1].value_or(false) != true ||
2250        overlap_1_3[2].value_or(true) != false) {
2251        std::cout << "[FAIL] : in test_overlaps() : overlaps (1, 3]" << std::endl;
2252        return;
2253    }
repr (pd_test_1_all.cpp:10906)
10896    std::cout << " -> tests passed" << std::endl;
10897}
10898
10899void pd_test_extension_index_repr() {
10900    std::cout << "========= repr =========================";
10901
10902    pandas::CategoricalArray arr({"a", "b", "c"});
10903    // Use ExtensionIndex<CategoricalArray> directly to test base class repr
10904    pandas::ExtensionIndex<pandas::CategoricalArray> idx(arr, "test");
10905
10906    std::string repr_str = idx.repr();
10907
10908    bool passed = (!repr_str.empty() && repr_str.find("ExtensionIndex") != std::string::npos);
10909    if (!passed) {
10910        std::cout << "  [FAIL] : in pd_test_extension_index_repr() : repr check failed" << std::endl;
10911        throw std::runtime_error("pd_test_extension_index_repr failed");
10912    }
10913
10914    std::cout << " -> tests passed" << std::endl;
10915}
right (pd_test_1_all.cpp:1910)
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);
1914
1915    pandas::IntervalArrayFloat64 arr1(left, right);
1916    if (arr1.size() != 3) {
1917        std::cout << "[FAIL] : in test_constructors() : array size" << std::endl;
1918        return;
1919    }
set_subtype_override (pd_test_3_all.cpp:24977)
24967    std::cout << "========= Interval repr float bounds ====================";
24968    pandas::Interval<double> iv(0.0, 1.5);
24969    if (iv.repr() != "Interval(0.0, 1.5, closed='right')")
24970        throw std::runtime_error("repr mismatch: " + iv.repr());
24971    std::cout << " -> tests passed" << std::endl;
24972}
24973
24974void pd_test_interval_repr_timedelta() {
24975    std::cout << "========= Interval repr timedelta subtype ===============";
24976    pandas::Interval<double> iv(0.0, 86400000000000.0);  // 1 day in nanos
24977    iv.set_subtype_override("timedelta64[ns]");
24978    std::string r = iv.repr();
24979    if (r.find("Timedelta") == std::string::npos)
24980        throw std::runtime_error("expected Timedelta in repr: " + r);
24981    if (r.find("1 days") == std::string::npos)
24982        throw std::runtime_error("expected '1 days' in repr: " + r);
24983    std::cout << " -> tests passed" << std::endl;
24984}
24985
24986void pd_test_interval_str_integer() {
24987    std::cout << "========= Interval to_string integer bounds =============";