Skip to content

Commit 800102f

Browse files
authored
feat: add is_pandas_index, is_modin_index, is_cudf_index, is_pandas_like_index utility functions (#1272)
* add is_index method to pandas-like methods * add test for is_pandas_index, add no cover for other libraries * add pandas and modin tests * remove modin from tests
1 parent 31e17ee commit 800102f

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

docs/api-reference/dependencies.md

+4
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,19 @@
1111
- get_polars
1212
- get_pyarrow
1313
- is_cudf_dataframe
14+
- is_cudf_index
1415
- is_cudf_series
1516
- is_dask_dataframe
1617
- is_ibis_table
1718
- is_into_series
1819
- is_modin_dataframe
20+
- is_modin_index
1921
- is_modin_series
2022
- is_numpy_array
2123
- is_pandas_dataframe
24+
- is_pandas_index
2225
- is_pandas_like_dataframe
26+
- is_pandas_like_index
2327
- is_pandas_like_series
2428
- is_pandas_series
2529
- is_polars_dataframe

narwhals/dependencies.py

+33-3
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ def is_pandas_series(ser: Any) -> TypeGuard[pd.Series[Any]]:
9898
return (pd := get_pandas()) is not None and isinstance(ser, pd.Series)
9999

100100

101+
def is_pandas_index(index: Any) -> TypeGuard[pd.Index]:
102+
"""Check whether `index` is a pandas Index without importing pandas."""
103+
return (pd := get_pandas()) is not None and isinstance(index, pd.Index)
104+
105+
101106
def is_modin_dataframe(df: Any) -> TypeGuard[mpd.DataFrame]:
102107
"""Check whether `df` is a modin DataFrame without importing modin."""
103108
return (mpd := get_modin()) is not None and isinstance(df, mpd.DataFrame)
@@ -108,6 +113,13 @@ def is_modin_series(ser: Any) -> TypeGuard[mpd.Series]:
108113
return (mpd := get_modin()) is not None and isinstance(ser, mpd.Series)
109114

110115

116+
def is_modin_index(index: Any) -> TypeGuard[mpd.Index]:
117+
"""Check whether `index` is a modin Index without importing modin."""
118+
return (mpd := get_modin()) is not None and isinstance(
119+
index, mpd.Index
120+
) # pragma: no cover
121+
122+
111123
def is_cudf_dataframe(df: Any) -> TypeGuard[cudf.DataFrame]:
112124
"""Check whether `df` is a cudf DataFrame without importing cudf."""
113125
return (cudf := get_cudf()) is not None and isinstance(df, cudf.DataFrame)
@@ -118,6 +130,13 @@ def is_cudf_series(ser: Any) -> TypeGuard[cudf.Series[Any]]:
118130
return (cudf := get_cudf()) is not None and isinstance(ser, cudf.Series)
119131

120132

133+
def is_cudf_index(index: Any) -> TypeGuard[cudf.Index]:
134+
"""Check whether `index` is a cudf Index without importing cudf."""
135+
return (cudf := get_cudf()) is not None and isinstance(
136+
index, cudf.Index
137+
) # pragma: no cover
138+
139+
121140
def is_dask_dataframe(df: Any) -> TypeGuard[dd.DataFrame]:
122141
"""Check whether `df` is a Dask DataFrame without importing Dask."""
123142
return (dd := get_dask_dataframe()) is not None and isinstance(df, dd.DataFrame)
@@ -174,13 +193,24 @@ def is_pandas_like_dataframe(df: Any) -> bool:
174193
return is_pandas_dataframe(df) or is_modin_dataframe(df) or is_cudf_dataframe(df)
175194

176195

177-
def is_pandas_like_series(arr: Any) -> bool:
196+
def is_pandas_like_series(ser: Any) -> bool:
178197
"""
179-
Check whether `arr` is a pandas-like Series without doing any imports
198+
Check whether `ser` is a pandas-like Series without doing any imports
180199
181200
By "pandas-like", we mean: pandas, Modin, cuDF.
182201
"""
183-
return is_pandas_series(arr) or is_modin_series(arr) or is_cudf_series(arr)
202+
return is_pandas_series(ser) or is_modin_series(ser) or is_cudf_series(ser)
203+
204+
205+
def is_pandas_like_index(index: Any) -> bool:
206+
"""
207+
Check whether `index` is a pandas-like Index without doing any imports
208+
209+
By "pandas-like", we mean: pandas, Modin, cuDF.
210+
"""
211+
return (
212+
is_pandas_index(index) or is_modin_index(index) or is_cudf_index(index)
213+
) # pragma: no cover
184214

185215

186216
def is_into_series(native_series: IntoSeries) -> bool:
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from __future__ import annotations
2+
3+
import pandas as pd
4+
5+
from narwhals.dependencies import is_pandas_index
6+
7+
8+
def test_is_pandas_index() -> None:
9+
data = [1, 2]
10+
s_pd = pd.Series(data)
11+
assert is_pandas_index(s_pd.index)
12+
assert not is_pandas_index(data)

0 commit comments

Comments
 (0)