diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e516d6c6ea..21b80e3fe8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ - Added support for `Series.between`. - Added support for `include_groups=False` in `DataFrameGroupBy.apply`. - Added support for `expand=True` in `Series.str.split`. +- Added support for `DataFrame.pop` and `Series.pop`. #### Bug Fixes diff --git a/docs/source/modin/supported/dataframe_supported.rst b/docs/source/modin/supported/dataframe_supported.rst index f86e0f0e772..ef243857063 100644 --- a/docs/source/modin/supported/dataframe_supported.rst +++ b/docs/source/modin/supported/dataframe_supported.rst @@ -311,7 +311,7 @@ Methods +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ | ``plot`` | D | | Performed locally on the client | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ -| ``pop`` | N | | | +| ``pop`` | Y | | | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ | ``pow`` | P | ``level`` | | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ diff --git a/docs/source/modin/supported/series_supported.rst b/docs/source/modin/supported/series_supported.rst index ec4a6665ca4..69830a44d0d 100644 --- a/docs/source/modin/supported/series_supported.rst +++ b/docs/source/modin/supported/series_supported.rst @@ -306,7 +306,7 @@ Methods +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ | ``plot`` | D | | Performed locally on the client | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ -| ``pop`` | N | | | +| ``pop`` | Y | | | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ | ``pow`` | P | ``level`` | | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ diff --git a/src/snowflake/snowpark/modin/plugin/docstrings/base.py b/src/snowflake/snowpark/modin/plugin/docstrings/base.py index 5c81b60389a..04944232a90 100644 --- a/src/snowflake/snowpark/modin/plugin/docstrings/base.py +++ b/src/snowflake/snowpark/modin/plugin/docstrings/base.py @@ -2346,6 +2346,43 @@ def pipe(): def pop(): """ Return item and drop from frame. Raise KeyError if not found. + + Parameters + ---------- + item : label + Label of column to be popped. + + Returns + ------- + Series + + Examples + -------- + >>> df = pd.DataFrame([('falcon', 'bird', 389.0), + ... ('parrot', 'bird', 24.0), + ... ('lion', 'mammal', 80.5), + ... ('monkey', 'mammal', np.nan)], + ... columns=('name', 'class', 'max_speed')) + >>> df + name class max_speed + 0 falcon bird 389.0 + 1 parrot bird 24.0 + 2 lion mammal 80.5 + 3 monkey mammal NaN + + >>> df.pop('class') + 0 bird + 1 bird + 2 mammal + 3 mammal + Name: class, dtype: object + + >>> df + name max_speed + 0 falcon 389.0 + 1 parrot 24.0 + 2 lion 80.5 + 3 monkey NaN """ def pow(): diff --git a/src/snowflake/snowpark/modin/plugin/docstrings/series.py b/src/snowflake/snowpark/modin/plugin/docstrings/series.py index b86e6f20d72..bf54d966648 100644 --- a/src/snowflake/snowpark/modin/plugin/docstrings/series.py +++ b/src/snowflake/snowpark/modin/plugin/docstrings/series.py @@ -2316,6 +2316,32 @@ def plot(): Make plot of Series. """ + def pop(): + """ + Return item and drops from series. Raise KeyError if not found. + + Parameters + ---------- + item : label + Index of the element that needs to be removed. + + Returns + ------- + Value that is popped from series. + + Examples + -------- + >>> ser = pd.Series([1, 2, 3]) + + >>> ser.pop(0) + 1 + + >>> ser + 1 2 + 2 3 + dtype: int64 + """ + @_create_operator_docstring(pandas.core.series.Series.pow, overwrite_existing=True) def pow(): pass diff --git a/src/snowflake/snowpark/modin/plugin/extensions/base_overrides.py b/src/snowflake/snowpark/modin/plugin/extensions/base_overrides.py index 7757d3964f8..643b04e07ee 100644 --- a/src/snowflake/snowpark/modin/plugin/extensions/base_overrides.py +++ b/src/snowflake/snowpark/modin/plugin/extensions/base_overrides.py @@ -261,11 +261,6 @@ def pipe(self, func, *args, **kwargs): # noqa: PR01, RT01, D200 pass # pragma: no cover -@register_base_not_implemented() -def pop(self, item): # noqa: PR01, RT01, D200 - pass # pragma: no cover - - @register_base_not_implemented() def reindex_like( self, other, method=None, copy=True, limit=None, tolerance=None diff --git a/src/snowflake/snowpark/modin/plugin/extensions/dataframe_overrides.py b/src/snowflake/snowpark/modin/plugin/extensions/dataframe_overrides.py index 702b356da8f..75748ff7106 100644 --- a/src/snowflake/snowpark/modin/plugin/extensions/dataframe_overrides.py +++ b/src/snowflake/snowpark/modin/plugin/extensions/dataframe_overrides.py @@ -383,11 +383,6 @@ def to_xml( pass # pragma: no cover -@register_dataframe_not_implemented() -def __delitem__(self, key): - pass # pragma: no cover - - @register_dataframe_accessor("style") @property def style(self): # noqa: RT01, D200 diff --git a/tests/integ/modin/frame/test_pop.py b/tests/integ/modin/frame/test_pop.py new file mode 100644 index 00000000000..4ccab432d0e --- /dev/null +++ b/tests/integ/modin/frame/test_pop.py @@ -0,0 +1,48 @@ +# +# Copyright (c) 2012-2025 Snowflake Computing Inc. All rights reserved. +# + +import numpy as np +import modin.pandas as pd +import pandas as native_pd +import pytest + +from tests.integ.modin.utils import assert_frame_equal, assert_series_equal +from tests.integ.utils.sql_counter import sql_count_checker + + +@sql_count_checker(query_count=2) +def test_pop(): + native_df = native_pd.DataFrame( + [ + ("falcon", "bird", 389.0), + ("parrot", "bird", 24.0), + ("lion", "mammal", 80.5), + ("monkey", "mammal", np.nan), + ], + columns=("name", "class", "max_speed"), + ) + snow_df = pd.DataFrame(native_df) + + native_popped_ser = native_df.pop("class") + snow_popped_ser = snow_df.pop("class") + + assert_series_equal(snow_popped_ser, native_popped_ser) + assert_frame_equal(snow_df, native_df) + + +@sql_count_checker(query_count=0) +def test_pop_not_found(): + native_df = native_pd.DataFrame( + [ + ("falcon", "bird", 389.0), + ("parrot", "bird", 24.0), + ("lion", "mammal", 80.5), + ("monkey", "mammal", np.nan), + ], + columns=("name", "class", "max_speed"), + ) + snow_df = pd.DataFrame(native_df) + + with pytest.raises(KeyError): + snow_df.pop("not_found") diff --git a/tests/integ/modin/series/test_pop.py b/tests/integ/modin/series/test_pop.py new file mode 100644 index 00000000000..43246496b0b --- /dev/null +++ b/tests/integ/modin/series/test_pop.py @@ -0,0 +1,33 @@ +# +# Copyright (c) 2012-2025 Snowflake Computing Inc. All rights reserved. +# + +import modin.pandas as pd +import pandas as native_pd +import pytest + +from tests.integ.modin.utils import assert_series_equal +from tests.integ.utils.sql_counter import sql_count_checker + + +@sql_count_checker(query_count=5, join_count=2) +def test_pop(): + native_ser = native_pd.Series([1, 2, 3]) + snow_ser = pd.Series(native_ser) + assert isinstance(snow_ser, pd.Series) + + native_popped_val = native_ser.pop(0) + snow_popped_val = snow_ser.pop(0) + + assert snow_popped_val == native_popped_val + assert_series_equal(snow_ser, native_ser) + + +@sql_count_checker(query_count=2, join_count=1) +def test_pop_not_found(): + native_ser = native_pd.Series([1, 2, 3]) + snow_ser = pd.Series(native_ser) + assert isinstance(snow_ser, pd.Series) + + with pytest.raises(KeyError): + snow_ser.pop(-1) diff --git a/tests/unit/modin/test_unsupported.py b/tests/unit/modin/test_unsupported.py index dace5a02a53..7b7d50587b2 100644 --- a/tests/unit/modin/test_unsupported.py +++ b/tests/unit/modin/test_unsupported.py @@ -80,7 +80,6 @@ def test_unsupported_general(general_method, kwargs): ["kurtosis", {}], ["mode", {}], ["pipe", {"func": ""}], - ["pop", {"item": ""}], ["prod", {}], ["product", {}], ["query", {"expr": ""}], @@ -157,7 +156,6 @@ def test_unsupported_df(df_method, kwargs): ["mode", {}], ["nbytes", {}], ["pipe", {"func": ""}], - ["pop", {"item": ""}], ["prod", {}], ["ravel", {}], ["reindex_like", {"other": ""}],