Repository: pandas-dev/pandas

Issue:
Define and document the order of index names vs column names in query eval
Current behavior is to use the index over the columns. I think it makes more sense to prefer the columns.

Current behavior:

```
In [7]: n = 10

In [8]: df = DataFrame(randint(40, 50, size=(n, 2)), columns=list('ab'))

In [9]: df.index.name = 'a'

In [10]: df
Out[10]:
    a   b
a
0  43  40
1  43  46
2  41  42
3  40  45
4  41  41
5  40  45
6  47  44
7  49  41
8  40  40
9  47  40

[10 rows x 2 columns]

In [11]: df.query('a > 5')
Out[11]:
    a   b
a
6  47  44
7  49  41
8  40  40
9  47  40

[4 rows x 2 columns]
```

New behavior:

```
In [10]: df
Out[10]:
    a   b
a
0  45  47
1  44  41
2  44  48
3  47  40
4  48  48
5  47  40
6  41  47
7  44  44
8  41  41
9  40  47

[10 rows x 2 columns]

In [11]: df.query('a > 43')
Out[11]:
    a   b
a
0  45  47
1  44  41
2  44  48
3  47  40
4  48  48
5  47  40
7  44  44

[7 rows x 2 columns]
```



Discussion:

Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -1855,7 +1855,7 @@ def eval(self, expr, **kwargs):
         kwargs['level'] = kwargs.pop('level', 0) + 1
         if resolvers is None:
             index_resolvers = self._get_index_resolvers()
-            resolvers = index_resolvers, dict(self.iteritems())
+            resolvers = dict(self.iteritems()), index_resolvers
         kwargs['target'] = self
         kwargs['resolvers'] = kwargs.get('resolvers', ()) + resolvers
         return _eval(expr, **kwargs)


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -12583,7 +12583,7 @@ def setUpClass(cls):
         super(TestDataFrameQueryNumExprPandas, cls).setUpClass()
         cls.engine = 'numexpr'
         cls.parser = 'pandas'
-        tm.skip_if_no_ne()
+        tm.skip_if_no_ne(cls.engine)
 
     @classmethod
     def tearDownClass(cls):
@@ -12867,6 +12867,31 @@ def test_query_undefined_local(self):
                                    "local variable 'c' is not defined"):
             df.query('a == @c', engine=engine, parser=parser)
 
+    def test_index_resolvers_come_after_columns_with_the_same_name(self):
+        n = 1
+        a = np.r_[20:101:20]
+
+        df = DataFrame({'index': a, 'b': np.random.randn(a.size)})
+        df.index.name = 'index'
+        result = df.query('index > 5', engine=self.engine, parser=self.parser)
+        expected = df[df['index'] > 5]
+        tm.assert_frame_equal(result, expected)
+
+        df = DataFrame({'index': a, 'b': np.random.randn(a.size)})
+        result = df.query('ilevel_0 > 5', engine=self.engine, parser=self.parser)
+        expected = df.loc[df.index[df.index > 5]]
+        tm.assert_frame_equal(result, expected)
+
+        df = DataFrame({'a': a, 'b': np.random.randn(a.size)})
+        df.index.name = 'a'
+        result = df.query('a > 5', engine=self.engine, parser=self.parser)
+        expected = df[df.a > 5]
+        tm.assert_frame_equal(result, expected)
+
+        result = df.query('index > 5', engine=self.engine, parser=self.parser)
+        expected = df.loc[df.index[df.index > 5]]
+        tm.assert_frame_equal(result, expected)
+
 
 class TestDataFrameQueryNumExprPython(TestDataFrameQueryNumExprPandas):