Repository: pandas-dev/pandas

Issue:
BUG/API: DataFrame.dtypes == 'categorical'
Should this work?

``` python
In [70]: cat = pd.Categorical(['a', 'b', 'c'])

In [71]: obj = pd.Series(['a', 'b', 'c'])

In [72]: num = pd.Series([1, 2, 3])

In [73]: df = pd.concat([pd.Series(cat), obj, num], axis=1, keys=['cat', 'obj', 'num'])

In [74]: df
Out[74]: 
  cat obj  num
0   a   a    1
1   b   b    2
2   c   c    3

In [75]: df.dtypes
Out[75]: 
cat    category
obj      object
num       int64
dtype: object

In [76]: df.dtypes == 'category'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-76-48fb3d0c49cf> in <module>()
----> 1 df.dtypes == 'category'

/Users/tom/Envs/py3/lib/python3.4/site-packages/pandas-0.14.1_291_g7a8a030-py3.4-macosx-10.9-x86_64.egg/pandas/core/ops.py in wrapper(self, other)
    579 
    580             # scalars
--> 581             res = na_op(values, other)
    582             if np.isscalar(res):
    583                 raise TypeError('Could not compare %s type with Series'

/Users/tom/Envs/py3/lib/python3.4/site-packages/pandas-0.14.1_291_g7a8a030-py3.4-macosx-10.9-x86_64.egg/pandas/core/ops.py in na_op(x, y)
    526             msg = "Cannot compare a Categorical for op {op} with type {typ}. If you want to \n" \
    527                   "compare values, use 'series <op> np.asarray(cat)'."
--> 528             raise TypeError(msg.format(op=op,typ=type(y)))
    529         if x.dtype == np.object_:
    530             if isinstance(y, list):

TypeError: Cannot compare a Categorical for op <built-in function eq> with type <class 'str'>. If you want to 
compare values, use 'series <op> np.asarray(cat)'.
```

For comparison

``` python
In [77]: df.dtypes == 'object'
Out[77]: 
cat    False
obj     True
num    False
dtype: bool

In [78]: df.dtypes == 'int64'
Out[78]: 
cat    False
obj    False
num     True
dtype: bool
```

This doesn't work either: `In [87]: df.dtypes == df.cat.dtype` (raise the same TypeError)



Discussion:
yep, i will fix (easy).

FYI, you should use `com.is_category_dtype` when testing in any event (in internal code)


Resolving patch:
diff --git a/pandas/core/ops.py b/pandas/core/ops.py
--- a/pandas/core/ops.py
+++ b/pandas/core/ops.py
@@ -522,7 +522,8 @@ def _comp_method_SERIES(op, name, str_rep, masker=False):
     code duplication.
     """
     def na_op(x, y):
-        if com.is_categorical_dtype(x) != com.is_categorical_dtype(y):
+
+        if com.is_categorical_dtype(x) != (not np.isscalar(y) and com.is_categorical_dtype(y)):
             msg = "Cannot compare a Categorical for op {op} with type {typ}. If you want to \n" \
                   "compare values, use 'series <op> np.asarray(cat)'."
             raise TypeError(msg.format(op=op,typ=type(y)))


Test patch:
diff --git a/pandas/tests/test_categorical.py b/pandas/tests/test_categorical.py
--- a/pandas/tests/test_categorical.py
+++ b/pandas/tests/test_categorical.py
@@ -785,6 +785,25 @@ def f():
         self.assertFalse(dtype == np.str_)
         self.assertFalse(np.str_ == dtype)
 
+        # GH8143
+        index = ['cat','obj','num']
+        cat = pd.Categorical(['a', 'b', 'c'])
+        obj = pd.Series(['a', 'b', 'c'])
+        num = pd.Series([1, 2, 3])
+        df = pd.concat([pd.Series(cat), obj, num], axis=1, keys=index)
+
+        result = df.dtypes == 'object'
+        expected = Series([False,True,False],index=index)
+        tm.assert_series_equal(result, expected)
+
+        result = df.dtypes == 'int64'
+        expected = Series([False,False,True],index=index)
+        tm.assert_series_equal(result, expected)
+
+        result = df.dtypes == 'category'
+        expected = Series([True,False,False],index=index)
+        tm.assert_series_equal(result, expected)
+
     def test_basic(self):
 
         # test basic creation / coercion of categoricals