Skip to content
Merged
1 change: 1 addition & 0 deletions docs/cudf/source/user_guide/api_docs/index_objects.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Properties
Index.empty
Index.has_duplicates
Index.hasnans
Index.inferred_type
Index.is_monotonic_increasing
Index.is_monotonic_decreasing
Index.is_unique
Expand Down
81 changes: 81 additions & 0 deletions python/cudf/cudf/core/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ def __init__(
# SingleColumnFrame.__init__(self, {name: column})
return None

@property
def _constructor(self):
return Index

@property
def _constructor_expanddim(self):
return cudf.MultiIndex
Expand Down Expand Up @@ -1891,6 +1895,35 @@ def _concat(cls, objs):
result.name = name
return result

@cached_property
def inferred_type(self) -> str:
"""
Return a string of the type inferred from the values.

Examples
--------
>>> import cudf
>>> idx = cudf.Index([1, 2, 3])
>>> idx
Index([1, 2, 3], dtype='int64')
>>> idx.inferred_type
'integer'
"""
if self._is_object():
if len(self) == 0:
return "empty"
else:
return "string"
elif self._is_integer():
return "integer"
elif self._is_floating():
return "floating"
elif self._is_boolean():
return "boolean"
raise NotImplementedError(
f"inferred_type not implemented for dtype {self.dtype}"
)

@_performance_tracking
def memory_usage(self, deep: bool = False) -> int:
return self._column.memory_usage
Expand Down Expand Up @@ -2607,6 +2640,14 @@ def name(self) -> Hashable:
def name(self, value: Hashable) -> None:
self._name = value

@property
def _constructor(self):
return RangeIndex

@cached_property
def inferred_type(self) -> str:
return "integer"

@property
@_performance_tracking
def _num_rows(self) -> int:
Expand Down Expand Up @@ -3640,6 +3681,14 @@ def strftime(self, date_format: str) -> Index:
self._column.strftime(date_format), name=self.name
)

@cached_property
def _constructor(self):
return DatetimeIndex

@cached_property
def inferred_type(self) -> str:
return "datetime64"

@cached_property
def asi8(self) -> cupy.ndarray:
return self._column.astype(np.dtype(np.int64)).values
Expand Down Expand Up @@ -4552,6 +4601,14 @@ def as_unit(self, unit: str, round_ok: bool = True) -> Self:
"""
raise NotImplementedError("as_unit is currently not implemented")

@cached_property
def _constructor(self):
return TimedeltaIndex

@cached_property
def inferred_type(self) -> str:
return "timedelta64"

@property
def freq(self) -> DateOffset | None:
raise NotImplementedError("freq is currently not implemented")
Expand Down Expand Up @@ -4850,6 +4907,14 @@ def from_codes(
def ordered(self) -> bool:
return self._column.ordered

@cached_property
def _constructor(self):
return CategoricalIndex

@cached_property
def inferred_type(self) -> str:
return "categorical"

@property
@_performance_tracking
def codes(self) -> Index:
Expand Down Expand Up @@ -5205,6 +5270,14 @@ def __init__(
def closed(self) -> Literal["left", "right", "neither", "both"]:
return self.dtype.closed

@property
def closed_left(self) -> bool:
return self.closed in ("left", "both")

@property
def closed_right(self) -> bool:
return self.closed in ("right", "both")

@classmethod
@_performance_tracking
def _from_column(
Expand Down Expand Up @@ -5290,6 +5363,14 @@ def from_breaks(
)._with_type_metadata(dtype)
return IntervalIndex._from_column(interval_col, name=name)

@cached_property
def _constructor(self):
return IntervalIndex

@cached_property
def inferred_type(self) -> str:
return "interval"

@classmethod
def from_arrays(
cls,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,23 @@ def test_index_ordered(ordered):
pd_ci = pd.CategoricalIndex([1, 2, 3], ordered=ordered)
cudf_ci = cudf.from_pandas(pd_ci)
assert pd_ci.ordered == cudf_ci.ordered


def test_categoricalindex_constructor():
gidx = cudf.CategoricalIndex(["a", "b", "c"])

assert gidx._constructor is cudf.CategoricalIndex


@pytest.mark.parametrize(
"data",
[
["a", "b", "c"],
[1, 2, 3],
pd.Categorical(["a", "b", "c"]),
],
)
def test_categoricalindex_inferred_type(data):
gidx = cudf.CategoricalIndex(data)
pidx = pd.CategoricalIndex(data)
assert_eq(gidx.inferred_type, pidx.inferred_type)
19 changes: 19 additions & 0 deletions python/cudf/cudf/tests/indexes/datetimeindex/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,22 @@ def test_datetime_index_is_unique_monotonic(testlist):
assert index.is_unique == index_pd.is_unique
assert index.is_monotonic_increasing == index_pd.is_monotonic_increasing
assert index.is_monotonic_decreasing == index_pd.is_monotonic_decreasing


def test_datetimeindex_constructor():
gidx = cudf.DatetimeIndex(["2020-01-01", "2020-01-02"])

assert gidx._constructor is cudf.DatetimeIndex


@pytest.mark.parametrize(
"dates",
[
pd.date_range("2020-01-01", periods=5),
pd.date_range("2020-01-01", periods=5, freq="h"),
],
)
def test_datetimeindex_inferred_type(dates):
gidx = cudf.DatetimeIndex(dates)
pidx = pd.DatetimeIndex(dates)
assert_eq(gidx.inferred_type, pidx.inferred_type)
23 changes: 23 additions & 0 deletions python/cudf/cudf/tests/indexes/index/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,26 @@ def test_index_contains_float_int(data, numeric_types_as_str, needle):
expected = needle in pidx

assert_eq(actual, expected)


def test_index_constructor():
gidx = cudf.Index([1, 2, 3])

assert gidx._constructor is cudf.Index


@pytest.mark.parametrize(
"data,expected_type",
[
([], "empty"),
([1, 2, 3], "int64"),
([1.0, 2.0, 3.0], "float64"),
(["a", "b", "c"], "string"),
([True, False, True], "boolean"),
],
)
def test_index_inferred_type(data, expected_type):
gidx = cudf.Index(data)
pidx = pd.Index(data)

assert_eq(gidx.inferred_type, pidx.inferred_type)
35 changes: 35 additions & 0 deletions python/cudf/cudf/tests/indexes/intervalindex/test_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (c) 2025, NVIDIA CORPORATION.
import pandas as pd
import pytest

import cudf
from cudf.testing import assert_eq


def test_intervalindex_constructor():
gidx = cudf.IntervalIndex.from_breaks([0, 1, 2, 3])

assert gidx._constructor is cudf.IntervalIndex


@pytest.mark.parametrize(
"closed",
["left", "right", "both", "neither"],
)
def test_intervalindex_inferred_type(closed):
gidx = cudf.IntervalIndex.from_breaks([0, 1, 2, 3], closed=closed)
pidx = pd.IntervalIndex.from_breaks([0, 1, 2, 3], closed=closed)
assert_eq(gidx.inferred_type, pidx.inferred_type)


@pytest.mark.parametrize(
"closed",
["left", "right", "both", "neither"],
)
def test_intervalindex_closed_left_right(closed):
"""Test closed_left and closed_right properties."""
gidx = cudf.IntervalIndex.from_breaks([0, 1, 2, 3], closed=closed)
pidx = pd.IntervalIndex.from_breaks([0, 1, 2, 3], closed=closed)

assert gidx.closed_left == pidx.closed_left
assert gidx.closed_right == pidx.closed_right
12 changes: 12 additions & 0 deletions python/cudf/cudf/tests/indexes/rangeindex/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,15 @@ def test_from_pandas_rangeindex():

assert_eq(idx1.values, idx2.values)
assert idx1.name == idx2.name


def test_rangeindex_constructor():
gidx = cudf.RangeIndex(10)

assert gidx._constructor is cudf.RangeIndex


def test_rangeindex_inferred_type():
gidx = cudf.RangeIndex(10)
pidx = pd.RangeIndex(10)
assert_eq(gidx.inferred_type, pidx.inferred_type)
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,22 @@ def test_error_values():
result = s.values
expected = cp.array([1, 2, 3]).view("timedelta64[ns]")
assert_eq(result, expected)


def test_timedeltaindex_constructor():
gidx = cudf.TimedeltaIndex([1, 2, 3])

assert gidx._constructor is cudf.TimedeltaIndex


@pytest.mark.parametrize(
"timedeltas",
[
pd.timedelta_range("1 day", periods=5),
[pd.Timedelta(days=i) for i in range(5)],
],
)
def test_timedeltaindex_inferred_type(timedeltas):
gidx = cudf.TimedeltaIndex(timedeltas)
pidx = pd.TimedeltaIndex(timedeltas)
assert_eq(gidx.inferred_type, pidx.inferred_type)
Loading