Repository: great-expectations/great_expectations

Issue:
Wrong index returned because _apply_row_condition uses DataFrame.reset_index(drop=True)
**Describe the bug**
When an expectation uses row_condition with the pandas parser, the wrong index is included in the expectation results json because PandasDataset._apply_row_condition uses DataFrame.reset_index(drop=True).

**To Reproduce**
Steps to reproduce the behavior:
1. Run the below code
2. Note that the incorrect output is returned when using row_condition (as this causes reset_index to run)
3. Comment out the two lines that are mentioned
4. Note that the correct output is returned when not using row_condition (as this reset_index does not run)
5. UN-Comment the two lines that are mentioned
6. Comment out `.reset_index(drop=True)` in great_expectations/dataset/pandas_dataset.py:PandasDataset._apply_row_condition 
7. Note that the correct output is returned when not using row_condition (as this reset_index does not run)

**Expected behavior**
The correct index of the bad values is returned.

**Environment (please complete the following information):**
 - Operating System: Linux & MacOS
 - Great Expectations Version: [e.g. 0.13.41]

**Additional context**
I depend on using the unexpected_index_list to drop "unexpected" rows from the dataframe that do not meet critical expectations.
Note: I would be happy to make this change. I have setup my development environment and made this change locally but just need help in understanding where tests need to be updated.

```
import great_expectations as ge
from great_expectations.data_context.types.base import DataContextConfig, DatasourceConfig, FilesystemStoreBackendDefaults
from great_expectations.data_context import BaseDataContext
import numpy as np
import pandas as pd
import os

data = {'VARIABLE_NAME': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', ],
        'VALUE': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ]}

df = pd.DataFrame(data)

abs_path = os.getcwd() + '/great_expectations'
domain_name = 'test'

data_context_config = DataContextConfig(
    datasources={
        "my_pandas_datasource": DatasourceConfig(
            class_name="PandasDatasource",
        )
    },
    store_backend_defaults=FilesystemStoreBackendDefaults(root_directory=abs_path),
)

context = BaseDataContext(project_config=data_context_config)

suite = context.create_expectation_suite(domain_name, overwrite_existing=True)

batch_kwargs = {
    "datasource": 'my_pandas_datasource',
    "dataset": df,
    "data_asset_name": domain_name,
}

batch = context.get_batch(batch_kwargs, "test")

print(batch)

batch.expect_column_values_to_be_between(
    column="VALUE", min_value=1, max_value=4,   # All values should fall outside this range
    row_condition='VARIABLE_NAME == "B"',       # All of B's value are > 5
    condition_parser='pandas',
    # Note that if we were to comment out the above two lines that trigger DataFrame.query
    # We would get the correct return set
    # This is because after we run query we run DataFrame.reset_index(drop=True)
    result_format={'result_format': 'COMPLETE'},
)
results = batch.validate()


index_list_unexpected = []
failed_results = [result for result in results['results'] if result['success'] is False]

for result in failed_results:
    rf = result['expectation_config']['kwargs'].get('result_format')
    if isinstance(rf, dict) and rf['result_format'] == "COMPLETE":
        unexpected_list = result['result'].get('unexpected_list')
        unexpected_index_list = result['result'].get('unexpected_index_list')
        index_list_unexpected += unexpected_index_list

print('index_list_unexpected:', index_list_unexpected)
print('unexpected_list:', unexpected_list)

print('This dataframe should have VARIABLE_NAME B rows 5-9 of values 5-9.')
print(df.loc[index_list_unexpected, :])
print('Instead it has VARIABLE_NAME A rows 0-4 of values 0-4... which were in our range.')


with open('validation_results.json', 'w') as f:
    f.write(str(results))
```


Discussion:

Resolving patch:
diff --git a/great_expectations/dataset/pandas_dataset.py b/great_expectations/dataset/pandas_dataset.py
--- a/great_expectations/dataset/pandas_dataset.py
+++ b/great_expectations/dataset/pandas_dataset.py
@@ -186,7 +186,7 @@ def inner_wrapper(
                 result_format = self.default_expectation_args["result_format"]
 
             if row_condition:
-                self = self.query(row_condition).reset_index(drop=True)
+                self = self.query(row_condition)
 
             series_A = self[column_A]
             series_B = self[column_B]
@@ -297,7 +297,7 @@ def inner_wrapper(
                 result_format = self.default_expectation_args["result_format"]
 
             if row_condition:
-                self = self.query(row_condition).reset_index(drop=True)
+                self = self.query(row_condition)
 
             test_df = self[column_list]
 
@@ -433,9 +433,7 @@ def _apply_row_condition(self, row_condition, condition_parser):
                 " and must be 'python' or 'pandas'"
             )
         else:
-            return self.query(row_condition, parser=condition_parser).reset_index(
-                drop=True
-            )
+            return self.query(row_condition, parser=condition_parser)
 
     def get_row_count(self):
         return self.shape[0]
diff --git a/great_expectations/execution_engine/pandas_execution_engine.py b/great_expectations/execution_engine/pandas_execution_engine.py
--- a/great_expectations/execution_engine/pandas_execution_engine.py
+++ b/great_expectations/execution_engine/pandas_execution_engine.py
@@ -432,9 +432,7 @@ def get_domain_records(
                 )
             else:
                 # Querying row condition
-                data = data.query(row_condition, parser=condition_parser).reset_index(
-                    drop=True
-                )
+                data = data.query(row_condition, parser=condition_parser)
 
         if "column" in domain_kwargs:
             return data


Test patch:
diff --git a/tests/execution_engine/test_pandas_execution_engine.py b/tests/execution_engine/test_pandas_execution_engine.py
--- a/tests/execution_engine/test_pandas_execution_engine.py
+++ b/tests/execution_engine/test_pandas_execution_engine.py
@@ -264,9 +264,13 @@ def test_get_domain_records_with_column_pair_domain():
     )
 
     expected_column_pair_df = pd.DataFrame(
-        {"a": [2, 3, 4, 6], "b": [3.0, 4.0, 5.0, 6.0], "c": [2.0, 3.0, 4.0, None]}
+        {
+            "a": [2, 3, 4, 6],
+            "b": [3.0, 4.0, 5.0, 6.0],
+            "c": [2.0, 3.0, 4.0, None],
+        },
+        index=[1, 2, 3, 5],
     )
-
     assert data.equals(
         expected_column_pair_df
     ), "Data does not match after getting full access compute domain"
@@ -283,7 +287,7 @@ def test_get_domain_records_with_column_pair_domain():
     data = data.astype(int)
 
     expected_column_pair_df = pd.DataFrame(
-        {"a": [2, 3, 4], "b": [3, 4, 5], "c": [2, 3, 4]}
+        {"a": [2, 3, 4], "b": [3, 4, 5], "c": [2, 3, 4]}, index=[1, 2, 3]
     )
 
     assert data.equals(
@@ -336,7 +340,7 @@ def test_get_domain_records_with_multicolumn_domain():
     data = data.astype(int)
 
     expected_multicolumn_df = pd.DataFrame(
-        {"a": [2, 3, 4, 5], "b": [3, 4, 5, 7], "c": [2, 3, 4, 6]}, index=[0, 1, 2, 4]
+        {"a": [2, 3, 4, 5], "b": [3, 4, 5, 7], "c": [2, 3, 4, 6]}, index=[1, 2, 3, 5]
     )
 
     assert data.equals(
@@ -468,7 +472,7 @@ def test_get_compute_domain_with_column_domain():
 def test_get_compute_domain_with_row_condition():
     engine = PandasExecutionEngine()
     df = pd.DataFrame({"a": [1, 2, 3, 4], "b": [2, 3, 4, None]})
-    expected_df = df[df["b"] > 2].reset_index()
+    expected_df = df[df["b"] > 2]
 
     # Loading batch data
     engine.load_batch_data(batch_data=df, batch_id="1234")
@@ -493,7 +497,7 @@ def test_get_compute_domain_with_row_condition():
 def test_get_compute_domain_with_unmeetable_row_condition():
     engine = PandasExecutionEngine()
     df = pd.DataFrame({"a": [1, 2, 3, 4], "b": [2, 3, 4, None]})
-    expected_df = df[df["b"] > 24].reset_index()
+    expected_df = df[df["b"] > 24]
 
     # Loading batch data
     engine.load_batch_data(batch_data=df, batch_id="1234")
diff --git a/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_be_between.json b/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_be_between.json
--- a/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_be_between.json
+++ b/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_be_between.json
@@ -187,7 +187,7 @@
       },
       "out" : {
         "success":false,
-        "unexpected_index_list": [0],
+        "unexpected_index_list": [3],
         "unexpected_list": ["slimy"]
       }
     }, {
diff --git a/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_equal.json b/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_equal.json
--- a/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_equal.json
+++ b/tests/test_definitions/column_map_expectations/expect_column_value_lengths_to_equal.json
@@ -111,7 +111,7 @@
       },
       "out" : {
         "success": false,
-        "unexpected_index_list": [0],
+        "unexpected_index_list": [3],
         "unexpected_list": ["slimy"]
       }
     },{
diff --git a/tests/test_definitions/column_map_expectations/expect_column_values_to_be_between.json b/tests/test_definitions/column_map_expectations/expect_column_values_to_be_between.json
--- a/tests/test_definitions/column_map_expectations/expect_column_values_to_be_between.json
+++ b/tests/test_definitions/column_map_expectations/expect_column_values_to_be_between.json
@@ -574,7 +574,7 @@
         },
         "out": {
           "unexpected_list": [9],
-          "unexpected_index_list": [0],
+          "unexpected_index_list": [8],
           "success": false
         }
       },{