Repository: pandas-dev/pandas

Issue:
DataFrame.describe(include=['O']) should include categorical columns
#### Code Sample, a copy-pastable example if possible

```python
In[1]: df = pd.DataFrame({'cat':pd.Categorical(['a','b','c']), 
                          'obj':['d', 'e', 'f'], 
                          'num': [1,2,3], 
                          'bool':[True,False,True],
                          'dt':[pd.Timestamp('2010-1-1'), pd.Timestamp('2010-2-1'), pd.Timestamp('2010-3-1')]})

In [2]: df.describe(include=['O'])
Out[2]:        
       obj
count    3
unique   3
top      f
freq     1

```
#### Problem description

For me it makes sense that when using `describe` on `object` data types, categorical data types should be included as well in the output. The docstrings even use the word categorical: "To limit it instead to categorical objects submit the ``numpy.object`` data type." It might make sense to add booleans and datetimes as well.

#### Expected Output

The result should mimic the output of `df.describe(include=['O', 'category'])`
```
       cat obj
count    3   3
unique   3   3
top      c   f
freq     1   1
```
#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------

commit: None
python: 3.6.1.final.0
python-bits: 64
OS: Darwin
OS-release: 15.6.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.20.2
pytest: 3.0.7
pip: 9.0.1
setuptools: 35.0.2
Cython: 0.25.2
numpy: 1.13.0
scipy: 0.19.0
xarray: None
IPython: 6.0.0
sphinx: 1.5.5
patsy: 0.4.1
dateutil: 2.6.0
pytz: 2017.2
blosc: None
bottleneck: 1.2.0
tables: 3.4.2
numexpr: 2.6.2
feather: None
matplotlib: 2.0.2
openpyxl: 2.4.7
xlrd: 1.0.0
xlwt: 1.2.0
xlsxwriter: 0.9.6
lxml: 3.7.3
bs4: 4.6.0
html5lib: 0.999999999
sqlalchemy: 1.1.9
pymysql: None
psycopg2: None
jinja2: 2.9.6
s3fs: None
pandas_gbq: None
pandas_datareader: 0.3.0.post
</details>



Discussion:
why? you are mixing 2 distinct and different data types. Better to be much more explicit.
The types are very closely related and they have the same output (count, unique, top and freq). Perhaps the bigger issue is with the wording of the docstrings. It literally uses the word 'categorical'. Maybe there could be an addition of a new word for 'category-like' data which would include object, category, bool and datetime.
yeah a re-wording of the doc-string with an example (similar to yours) would be helpful. a PR would be great.
There is still some inconsistency. `np.number` refers to multiple distinct and different data types. I was hoping there was a similar reference that would capture both categorical and object since they are essentially the same. 

Also, If the dataframe consists of only categoricals and objects then `describe` will output both by default. 
``np.number`` is a composite dtype.  nothing that both captures ``np.object`` and ``category``
Agreed that we should clarify the docs here, and not change the behavior.

It is inconsistent that `np.number` selects all its subtypes, but `object` doesn't, but that's an unfortunate consequence of the type system we have to work with. I think the ability to select `object` and `categorical` dtypes independently is more useful.
Agreed, behavior should stay the same. Still wish there was something analogous to `np.number`. 

Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -6352,20 +6352,22 @@ def describe(self, percentiles=None, include=None, exclude=None):
             - A list-like of dtypes : Limits the results to the
               provided data types.
               To limit the result to numeric types submit
-              ``numpy.number``. To limit it instead to categorical
-              objects submit the ``numpy.object`` data type. Strings
+              ``numpy.number``. To limit it instead to object columns submit
+              the ``numpy.object`` data type. Strings
               can also be used in the style of
-              ``select_dtypes`` (e.g. ``df.describe(include=['O'])``)
+              ``select_dtypes`` (e.g. ``df.describe(include=['O'])``). To
+              select pandas categorical columns, use ``'category'``
             - None (default) : The result will include all numeric columns.
         exclude : list-like of dtypes or None (default), optional,
             A black list of data types to omit from the result. Ignored
             for ``Series``. Here are the options:
 
             - A list-like of dtypes : Excludes the provided data types
-              from the result. To select numeric types submit
-              ``numpy.number``. To select categorical objects submit the data
+              from the result. To exclude numeric types submit
+              ``numpy.number``. To exclude object columns submit the data
               type ``numpy.object``. Strings can also be used in the style of
-              ``select_dtypes`` (e.g. ``df.describe(include=['O'])``)
+              ``select_dtypes`` (e.g. ``df.describe(include=['O'])``). To
+              exclude pandas categorical columns, use ``'category'``
             - None (default) : The result will exclude nothing.
 
         Returns
@@ -6390,9 +6392,11 @@ def describe(self, percentiles=None, include=None, exclude=None):
         among those with the highest count.
 
         For mixed data types provided via a ``DataFrame``, the default is to
-        return only an analysis of numeric columns. If ``include='all'``
-        is provided as an option, the result will include a union of
-        attributes of each type.
+        return only an analysis of numeric columns. If the dataframe consists
+        only of object and categorical data without any numeric columns, the
+        default is to return an analysis of both the object and categorical
+        columns. If ``include='all'`` is provided as an option, the result
+        will include a union of attributes of each type.
 
         The `include` and `exclude` parameters can be used to limit
         which columns in a ``DataFrame`` are analyzed for the output.
@@ -6442,8 +6446,10 @@ def describe(self, percentiles=None, include=None, exclude=None):
         Describing a ``DataFrame``. By default only numeric fields
         are returned.
 
-        >>> df = pd.DataFrame([[1, 'a'], [2, 'b'], [3, 'c']],
-        ...                   columns=['numeric', 'object'])
+        >>> df = pd.DataFrame({ 'object': ['a', 'b', 'c'],
+        ...                     'numeric': [1, 2, 3],
+        ...                     'categorical': pd.Categorical(['d','e','f'])
+        ...                   })
         >>> df.describe()
                numeric
         count      3.0
@@ -6458,18 +6464,18 @@ def describe(self, percentiles=None, include=None, exclude=None):
         Describing all columns of a ``DataFrame`` regardless of data type.
 
         >>> df.describe(include='all')
-                numeric object
-        count       3.0      3
-        unique      NaN      3
-        top         NaN      b
-        freq        NaN      1
-        mean        2.0    NaN
-        std         1.0    NaN
-        min         1.0    NaN
-        25%         1.5    NaN
-        50%         2.0    NaN
-        75%         2.5    NaN
-        max         3.0    NaN
+                categorical  numeric object
+        count            3      3.0      3
+        unique           3      NaN      3
+        top              f      NaN      c
+        freq             1      NaN      1
+        mean           NaN      2.0    NaN
+        std            NaN      1.0    NaN
+        min            NaN      1.0    NaN
+        25%            NaN      1.5    NaN
+        50%            NaN      2.0    NaN
+        75%            NaN      2.5    NaN
+        max            NaN      3.0    NaN
 
         Describing a column from a ``DataFrame`` by accessing it as
         an attribute.
@@ -6504,30 +6510,42 @@ def describe(self, percentiles=None, include=None, exclude=None):
                object
         count       3
         unique      3
-        top         b
+        top         c
         freq        1
 
+        Including only categorical columns from a ``DataFrame`` description.
+
+        >>> df.describe(include=['category'])
+               categorical
+        count            3
+        unique           3
+        top              f
+        freq             1
+
         Excluding numeric columns from a ``DataFrame`` description.
 
         >>> df.describe(exclude=[np.number])
-               object
-        count       3
-        unique      3
-        top         b
-        freq        1
+               categorical object
+        count            3      3
+        unique           3      3
+        top              f      c
+        freq             1      1
 
         Excluding object columns from a ``DataFrame`` description.
 
         >>> df.describe(exclude=[np.object])
-               numeric
-        count      3.0
-        mean       2.0
-        std        1.0
-        min        1.0
-        25%        1.5
-        50%        2.0
-        75%        2.5
-        max        3.0
+                categorical  numeric
+        count            3      3.0
+        unique           3      NaN
+        top              f      NaN
+        freq             1      NaN
+        mean           NaN      2.0
+        std            NaN      1.0
+        min            NaN      1.0
+        25%            NaN      1.5
+        50%            NaN      2.0
+        75%            NaN      2.5
+        max            NaN      3.0
 
         See Also
         --------


Test patch: