Skip to content

Commit 55acd2c

Browse files
committed
Deprecate NDFrame.filter
1 parent 03b3c8f commit 55acd2c

File tree

3 files changed

+18
-124
lines changed

3 files changed

+18
-124
lines changed

doc/source/whatsnew/v1.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Other API changes
5454
Deprecations
5555
~~~~~~~~~~~~
5656

57-
-
57+
- :meth:`DataFrame.filter` and :meth:`Series.filter` are deprecated. (:issue:`26642`)
5858
-
5959

6060
.. _whatsnew_1000.prior_deprecations:

pandas/core/generic.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -4590,7 +4590,11 @@ def filter(self, items=None, like=None, regex=None, axis=None):
45904590
Subset rows or columns of dataframe according to labels in
45914591
the specified index.
45924592
4593-
Note that this routine does not filter a dataframe on its
4593+
.. deprecated:: 1.0
4594+
Use .loc instead, e.g. for regular expressions
4595+
use .loc(regex=True)[:, "^col_"]
4596+
4597+
Note that this method does not filter a dataframe on its
45944598
contents. The filter is applied to the labels of the index.
45954599
45964600
Parameters
@@ -4644,6 +4648,15 @@ def filter(self, items=None, like=None, regex=None, axis=None):
46444648
one two three
46454649
rabbit 4 5 6
46464650
"""
4651+
import re
4652+
4653+
warnings.warn(
4654+
"DataFrame/Series.filter is deprecated "
4655+
"and will be removed in a future version",
4656+
FutureWarning,
4657+
stacklevel=2,
4658+
)
4659+
46474660
nkw = com.count_not_none(items, like, regex)
46484661
if nkw > 1:
46494662
raise TypeError(

pandas/tests/frame/test_axis_select_reindex.py

+3-122
Original file line numberDiff line numberDiff line change
@@ -807,128 +807,9 @@ def test_align_series_combinations(self):
807807
tm.assert_series_equal(res1, exp2)
808808
tm.assert_frame_equal(res2, exp1)
809809

810-
def test_filter(self, float_frame, float_string_frame):
811-
# Items
812-
filtered = float_frame.filter(["A", "B", "E"])
813-
assert len(filtered.columns) == 2
814-
assert "E" not in filtered
815-
816-
filtered = float_frame.filter(["A", "B", "E"], axis="columns")
817-
assert len(filtered.columns) == 2
818-
assert "E" not in filtered
819-
820-
# Other axis
821-
idx = float_frame.index[0:4]
822-
filtered = float_frame.filter(idx, axis="index")
823-
expected = float_frame.reindex(index=idx)
824-
tm.assert_frame_equal(filtered, expected)
825-
826-
# like
827-
fcopy = float_frame.copy()
828-
fcopy["AA"] = 1
829-
830-
filtered = fcopy.filter(like="A")
831-
assert len(filtered.columns) == 2
832-
assert "AA" in filtered
833-
834-
# like with ints in column names
835-
df = DataFrame(0.0, index=[0, 1, 2], columns=[0, 1, "_A", "_B"])
836-
filtered = df.filter(like="_")
837-
assert len(filtered.columns) == 2
838-
839-
# regex with ints in column names
840-
# from PR #10384
841-
df = DataFrame(0.0, index=[0, 1, 2], columns=["A1", 1, "B", 2, "C"])
842-
expected = DataFrame(
843-
0.0, index=[0, 1, 2], columns=pd.Index([1, 2], dtype=object)
844-
)
845-
filtered = df.filter(regex="^[0-9]+$")
846-
tm.assert_frame_equal(filtered, expected)
847-
848-
expected = DataFrame(0.0, index=[0, 1, 2], columns=[0, "0", 1, "1"])
849-
# shouldn't remove anything
850-
filtered = expected.filter(regex="^[0-9]+$")
851-
tm.assert_frame_equal(filtered, expected)
852-
853-
# pass in None
854-
with pytest.raises(TypeError, match="Must pass"):
855-
float_frame.filter()
856-
with pytest.raises(TypeError, match="Must pass"):
857-
float_frame.filter(items=None)
858-
with pytest.raises(TypeError, match="Must pass"):
859-
float_frame.filter(axis=1)
860-
861-
# test mutually exclusive arguments
862-
with pytest.raises(TypeError, match="mutually exclusive"):
863-
float_frame.filter(items=["one", "three"], regex="e$", like="bbi")
864-
with pytest.raises(TypeError, match="mutually exclusive"):
865-
float_frame.filter(items=["one", "three"], regex="e$", axis=1)
866-
with pytest.raises(TypeError, match="mutually exclusive"):
867-
float_frame.filter(items=["one", "three"], regex="e$")
868-
with pytest.raises(TypeError, match="mutually exclusive"):
869-
float_frame.filter(items=["one", "three"], like="bbi", axis=0)
870-
with pytest.raises(TypeError, match="mutually exclusive"):
871-
float_frame.filter(items=["one", "three"], like="bbi")
872-
873-
# objects
874-
filtered = float_string_frame.filter(like="foo")
875-
assert "foo" in filtered
876-
877-
# unicode columns, won't ascii-encode
878-
df = float_frame.rename(columns={"B": "\u2202"})
879-
filtered = df.filter(like="C")
880-
assert "C" in filtered
881-
882-
def test_filter_regex_search(self, float_frame):
883-
fcopy = float_frame.copy()
884-
fcopy["AA"] = 1
885-
886-
# regex
887-
filtered = fcopy.filter(regex="[A]+")
888-
assert len(filtered.columns) == 2
889-
assert "AA" in filtered
890-
891-
# doesn't have to be at beginning
892-
df = DataFrame(
893-
{"aBBa": [1, 2], "BBaBB": [1, 2], "aCCa": [1, 2], "aCCaBB": [1, 2]}
894-
)
895-
896-
result = df.filter(regex="BB")
897-
exp = df[[x for x in df.columns if "BB" in x]]
898-
assert_frame_equal(result, exp)
899-
900-
@pytest.mark.parametrize(
901-
"name,expected",
902-
[
903-
("a", DataFrame({"a": [1, 2]})),
904-
("a", DataFrame({"a": [1, 2]})),
905-
("あ", DataFrame({"あ": [3, 4]})),
906-
],
907-
)
908-
def test_filter_unicode(self, name, expected):
909-
# GH13101
910-
df = DataFrame({"a": [1, 2], "あ": [3, 4]})
911-
912-
assert_frame_equal(df.filter(like=name), expected)
913-
assert_frame_equal(df.filter(regex=name), expected)
914-
915-
@pytest.mark.parametrize("name", ["a", "a"])
916-
def test_filter_bytestring(self, name):
917-
# GH13101
918-
df = DataFrame({b"a": [1, 2], b"b": [3, 4]})
919-
expected = DataFrame({b"a": [1, 2]})
920-
921-
assert_frame_equal(df.filter(like=name), expected)
922-
assert_frame_equal(df.filter(regex=name), expected)
923-
924-
def test_filter_corner(self):
925-
empty = DataFrame()
926-
927-
result = empty.filter([])
928-
assert_frame_equal(result, empty)
929-
930-
result = empty.filter(like="foo")
931-
assert_frame_equal(result, empty)
810+
def test_filter_deprecated(self, float_frame):
811+
with tm.assert_produces_warning(FutureWarning):
812+
float_frame.filter(["A", "B", "E"])
932813

933814
def test_take(self, float_frame):
934815
# homogeneous

0 commit comments

Comments
 (0)