Skip to content

DEPR: remove previously-deprecated get_value, set_value #27377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Deprecations

Removal of prior version deprecations/changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- Removed the previously deprecated :meth:`Series.get_value`, :meth:`Series.set_value`, :meth:`DataFrame.get_value`, :meth:`DataFrame.set_value` (:issue:`17739`)
-
-

Expand Down
38 changes: 3 additions & 35 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def _constructor(self):

_constructor_sliced = Series # type: Type[Series]
_deprecations = NDFrame._deprecations | frozenset(
["get_value", "set_value", "from_items"]
["from_items"]
) # type: FrozenSet[str]
_accessors = set() # type: Set[str]

Expand Down Expand Up @@ -2787,13 +2787,10 @@ def _unpickle_matrix_compat(self, state): # pragma: no cover
# ----------------------------------------------------------------------
# Getting and setting elements

def get_value(self, index, col, takeable=False):
def _get_value(self, index, col, takeable: bool = False):
"""
Quickly retrieve single value at passed column and index.

.. deprecated:: 0.21.0
Use .at[] or .iat[] accessors instead.

Parameters
----------
index : row label
Expand All @@ -2804,18 +2801,6 @@ def get_value(self, index, col, takeable=False):
-------
scalar
"""

warnings.warn(
"get_value is deprecated and will be removed "
"in a future release. Please use "
".at[] or .iat[] accessors instead",
FutureWarning,
stacklevel=2,
)
return self._get_value(index, col, takeable=takeable)

def _get_value(self, index, col, takeable=False):

if takeable:
series = self._iget_item_cache(col)
return com.maybe_box_datetimelike(series._values[index])
Expand All @@ -2839,15 +2824,10 @@ def _get_value(self, index, col, takeable=False):
index = self.index.get_loc(index)
return self._get_value(index, col, takeable=True)

_get_value.__doc__ = get_value.__doc__

def set_value(self, index, col, value, takeable=False):
def _set_value(self, index, col, value, takeable: bool = False):
"""
Put single value at passed column and index.

.. deprecated:: 0.21.0
Use .at[] or .iat[] accessors instead.

Parameters
----------
index : row label
Expand All @@ -2861,16 +2841,6 @@ def set_value(self, index, col, value, takeable=False):
If label pair is contained, will be reference to calling DataFrame,
otherwise a new object.
"""
warnings.warn(
"set_value is deprecated and will be removed "
"in a future release. Please use "
".at[] or .iat[] accessors instead",
FutureWarning,
stacklevel=2,
)
return self._set_value(index, col, value, takeable=takeable)

def _set_value(self, index, col, value, takeable=False):
try:
if takeable is True:
series = self._iget_item_cache(col)
Expand All @@ -2891,8 +2861,6 @@ def _set_value(self, index, col, value, takeable=False):

return self

_set_value.__doc__ = set_value.__doc__

def _ixs(self, i: int, axis: int = 0):
"""
Parameters
Expand Down
38 changes: 4 additions & 34 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class Series(base.IndexOpsMixin, generic.NDFrame):
_accessors = {"dt", "cat", "str", "sparse"}
# tolist is not actually deprecated, just suppressed in the __dir__
_deprecations = generic.NDFrame._deprecations | frozenset(
["asobject", "reshape", "get_value", "set_value", "valid", "tolist"]
["asobject", "reshape", "valid", "tolist"]
)

# Override cache_readonly bc Series is mutable
Expand Down Expand Up @@ -1367,13 +1367,10 @@ def repeat(self, repeats, axis=None):
new_values = self._values.repeat(repeats)
return self._constructor(new_values, index=new_index).__finalize__(self)

def get_value(self, label, takeable=False):
def _get_value(self, label, takeable: bool = False):
"""
Quickly retrieve single value at passed index label.

.. deprecated:: 0.21.0
Please use .at[] or .iat[] accessors.

Parameters
----------
label : object
Expand All @@ -1383,29 +1380,14 @@ def get_value(self, label, takeable=False):
-------
scalar value
"""
warnings.warn(
"get_value is deprecated and will be removed "
"in a future release. Please use "
".at[] or .iat[] accessors instead",
FutureWarning,
stacklevel=2,
)
return self._get_value(label, takeable=takeable)

def _get_value(self, label, takeable=False):
if takeable is True:
if takeable:
return com.maybe_box_datetimelike(self._values[label])
return self.index.get_value(self._values, label)

_get_value.__doc__ = get_value.__doc__

def set_value(self, label, value, takeable=False):
def _set_value(self, label, value, takeable: bool = False):
"""
Quickly set single value at passed label.

.. deprecated:: 0.21.0
Please use .at[] or .iat[] accessors.

If label is not contained, a new object is created with the label
placed at the end of the result index.

Expand All @@ -1423,16 +1405,6 @@ def set_value(self, label, value, takeable=False):
If label is contained, will be reference to calling Series,
otherwise a new object.
"""
warnings.warn(
"set_value is deprecated and will be removed "
"in a future release. Please use "
".at[] or .iat[] accessors instead",
FutureWarning,
stacklevel=2,
)
return self._set_value(label, value, takeable=takeable)

def _set_value(self, label, value, takeable=False):
try:
if takeable:
self._values[label] = value
Expand All @@ -1445,8 +1417,6 @@ def _set_value(self, label, value, takeable=False):

return self

_set_value.__doc__ = set_value.__doc__

def reset_index(self, level=None, drop=False, name=None, inplace=False):
"""
Generate a new DataFrame or Series with the index reset.
Expand Down
3 changes: 1 addition & 2 deletions pandas/tests/frame/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ def test_getitem_pop_assign_name(self, float_frame):
def test_get_value(self, float_frame):
for idx in float_frame.index:
for col in float_frame.columns:
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
result = float_frame.get_value(idx, col)
result = float_frame._get_value(idx, col)
expected = float_frame[col][idx]
tm.assert_almost_equal(result, expected)

Expand Down
12 changes: 4 additions & 8 deletions pandas/tests/frame/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,8 @@ def test_constructor_dict(self):
# Dict with None value
frame_none = DataFrame(dict(a=None), index=[0])
frame_none_list = DataFrame(dict(a=[None]), index=[0])
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
assert frame_none.get_value(0, "a") is None
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
assert frame_none_list.get_value(0, "a") is None
assert frame_none._get_value(0, "a") is None
assert frame_none_list._get_value(0, "a") is None
tm.assert_frame_equal(frame_none, frame_none_list)

# GH10856
Expand Down Expand Up @@ -702,17 +700,15 @@ def test_nested_dict_frame_constructor(self):
data = {}
for col in df.columns:
for row in df.index:
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
data.setdefault(col, {})[row] = df.get_value(row, col)
data.setdefault(col, {})[row] = df._get_value(row, col)

result = DataFrame(data, columns=rng)
tm.assert_frame_equal(result, df)

data = {}
for col in df.columns:
for row in df.index:
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
data.setdefault(row, {})[col] = df.get_value(row, col)
data.setdefault(row, {})[col] = df._get_value(row, col)

result = DataFrame(data, index=rng).T
tm.assert_frame_equal(result, df)
Expand Down
42 changes: 15 additions & 27 deletions pandas/tests/frame/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1849,8 +1849,7 @@ def test_getitem_list_duplicates(self):
def test_get_value(self, float_frame):
for idx in float_frame.index:
for col in float_frame.columns:
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
result = float_frame.get_value(idx, col)
result = float_frame._get_value(idx, col)
expected = float_frame[col][idx]
assert result == expected

Expand Down Expand Up @@ -1905,51 +1904,42 @@ def test_lookup_raises(self, float_frame):
def test_set_value(self, float_frame):
for idx in float_frame.index:
for col in float_frame.columns:
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
float_frame.set_value(idx, col, 1)
float_frame._set_value(idx, col, 1)
assert float_frame[col][idx] == 1

def test_set_value_resize(self, float_frame):

with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res = float_frame.set_value("foobar", "B", 0)
res = float_frame._set_value("foobar", "B", 0)
assert res is float_frame
assert res.index[-1] == "foobar"
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
assert res.get_value("foobar", "B") == 0
assert res._get_value("foobar", "B") == 0

float_frame.loc["foobar", "qux"] = 0
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
assert float_frame.get_value("foobar", "qux") == 0
assert float_frame._get_value("foobar", "qux") == 0

res = float_frame.copy()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res3 = res.set_value("foobar", "baz", "sam")
res3 = res._set_value("foobar", "baz", "sam")
assert res3["baz"].dtype == np.object_

res = float_frame.copy()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res3 = res.set_value("foobar", "baz", True)
res3 = res._set_value("foobar", "baz", True)
assert res3["baz"].dtype == np.object_

res = float_frame.copy()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res3 = res.set_value("foobar", "baz", 5)
res3 = res._set_value("foobar", "baz", 5)
assert is_float_dtype(res3["baz"])
assert isna(res3["baz"].drop(["foobar"])).all()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
msg = "could not convert string to float: 'sam'"
with pytest.raises(ValueError, match=msg):
res3.set_value("foobar", "baz", "sam")
msg = "could not convert string to float: 'sam'"
with pytest.raises(ValueError, match=msg):
res3._set_value("foobar", "baz", "sam")

def test_set_value_with_index_dtype_change(self):
df_orig = DataFrame(np.random.randn(3, 3), index=range(3), columns=list("ABC"))

# this is actually ambiguous as the 2 is interpreted as a positional
# so column is not created
df = df_orig.copy()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
df.set_value("C", 2, 1.0)
df._set_value("C", 2, 1.0)
assert list(df.index) == list(df_orig.index) + ["C"]
# assert list(df.columns) == list(df_orig.columns) + [2]

Expand All @@ -1960,8 +1950,7 @@ def test_set_value_with_index_dtype_change(self):

# create both new
df = df_orig.copy()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
df.set_value("C", "D", 1.0)
df._set_value("C", "D", 1.0)
assert list(df.index) == list(df_orig.index) + ["C"]
assert list(df.columns) == list(df_orig.columns) + ["D"]

Expand All @@ -1974,9 +1963,8 @@ def test_get_set_value_no_partial_indexing(self):
# partial w/ MultiIndex raise exception
index = MultiIndex.from_tuples([(0, 1), (0, 2), (1, 1), (1, 2)])
df = DataFrame(index=index, columns=range(4))
Copy link
Contributor

@jreback jreback Jul 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would blow most/all of the _get_value and _set_value test away

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im not sure we have other tests for _get_value/_set_value, which are still used internally

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thought to migrating it to test_interals then? I can see the value of separating these out from other tests at the very least

with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
with pytest.raises(KeyError, match=r"^0$"):
df.get_value(0, 1)
with pytest.raises(KeyError, match=r"^0$"):
df._get_value(0, 1)

def test_single_element_ix_dont_upcast(self, float_frame):
float_frame["E"] = 1
Expand Down
11 changes: 5 additions & 6 deletions pandas/tests/series/indexing/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,14 @@ def test_series_set_value():
dates = [datetime(2001, 1, 1), datetime(2001, 1, 2)]
index = DatetimeIndex(dates)

with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
s = Series().set_value(dates[0], 1.0)
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
s2 = s.set_value(dates[1], np.nan)
s = Series()._set_value(dates[0], 1.0)
s2 = s._set_value(dates[1], np.nan)

exp = Series([1.0, np.nan], index=index)
expected = Series([1.0, np.nan], index=index)

assert_series_equal(s2, exp)
assert_series_equal(s2, expected)

# FIXME: dont leave commented-out
# s = Series(index[:1], index[:1])
# s2 = s.set_value(dates[1], index[1])
# assert s2.values.dtype == 'M8[ns]'
Expand Down
6 changes: 2 additions & 4 deletions pandas/tests/series/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,13 @@ def test_setitem_dtypes():

def test_set_value(test_data):
idx = test_data.ts.index[10]
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res = test_data.ts.set_value(idx, 0)
res = test_data.ts._set_value(idx, 0)
assert res is test_data.ts
assert test_data.ts[idx] == 0

# equiv
s = test_data.series.copy()
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
res = s.set_value("foobar", 0)
res = s._set_value("foobar", 0)
assert res is s
assert res.index[-1] == "foobar"
assert res["foobar"] == 0
Expand Down