Skip to content
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