Repository: pyjanitor-devs/pyjanitor

Issue:
filtering with nice strings in between
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.query.html

The `.query()` method opens up a ton of possibilities for us! We can make a series of specific filtering functions, I believe.


Discussion:

Resolving patch:
diff --git a/janitor/functions.py b/janitor/functions.py
--- a/janitor/functions.py
+++ b/janitor/functions.py
@@ -546,12 +546,16 @@ def fill_empty(df, columns, value):
         for col in columns:
             assert (
                 col in df.columns
-            ), "{col} missing from dataframe columns!".format(col=col)
+            ), "{col} missing from dataframe columns!".format(
+                col=col
+            )
             df[col] = df[col].fillna(value)
     else:
         assert (
             columns in df.columns
-        ), "{col} missing from dataframe columns!".format(col=columns)
+        ), "{col} missing from dataframe columns!".format(
+            col=columns
+        )
         df[columns] = df[columns].fillna(value)
 
     return df
@@ -738,7 +742,11 @@ def filter_string(
     :param complement: Whether to return the complement of the filter or not.
     """
     criteria = df[column].str.contains(search_string)
-    return filter_on(df, criteria, complement=complement)
+    # return filter_on(df, criteria, complement=complement)
+    if complement:
+        return df[~criteria]
+    else:
+        return df[criteria]
 
 
 @pf.register_dataframe_method
@@ -751,7 +759,7 @@ def filter_on(df, criteria, complement=False):
     .. code-block:: python
 
         df = (pd.DataFrame(...)
-              .filter_on(df['value'] < 3, complement=False)
+              .filter_on('value < 3', complement=False)
               ...)  # chain on more data preprocessing.
 
     This stands in contrast to the in-place syntax that is usually used:
@@ -769,7 +777,7 @@ def filter_on(df, criteria, complement=False):
     .. code-block:: python
 
         df = filter_on(df,
-                       df['value'] < 3,
+                       'value < 3',
                        complement=False)
 
     Method chaining example:
@@ -777,8 +785,7 @@ def filter_on(df, criteria, complement=False):
     .. code-block:: python
 
         df = (pd.DataFrame(...)
-              .filter_on(df['value'] < 3
-                             complement=False)
+              .filter_on('value < 3', complement=False)
               ...)
 
     Credit to Brant Peterson for the name.
@@ -789,9 +796,9 @@ def filter_on(df, criteria, complement=False):
     :param complement: Whether to return the complement of the filter or not.
     """
     if complement:
-        return df[~criteria]
+        return df.query("not " + criteria)
     else:
-        return df[criteria]
+        return df.query(criteria)
 
 
 @pf.register_dataframe_method


Test patch:
diff --git a/tests/test_functions.py b/tests/test_functions.py
--- a/tests/test_functions.py
+++ b/tests/test_functions.py
@@ -527,12 +527,12 @@ def test_filter_string_complement(dataframe):
 
 
 def test_filter_on(dataframe):
-    df = filter_on(dataframe, dataframe["a"] == 3)
+    df = filter_on(dataframe, "a == 3")
     assert len(df) == 3
 
 
 def test_filter_on_complement(dataframe):
-    df = filter_on(dataframe, dataframe["a"] == 3, complement=True)
+    df = filter_on(dataframe, "a == 3", complement=True)
     assert len(df) == 6