Categorical fixups

Some fixups for Categoricals.

Fixes: #3678
Not sure hwat makes it "index-like", but currently `cat._levels` and the public accessor `cat.levels` is an index, but `cat._codes` and the public accessor `cat.codes` is a `np.ndarray`:

```python
In[47]: type(pd.Categorical([1]).codes)
Out[47]: numpy.ndarray
In[48]: type(pd.Categorical([1])._codes)
Out[48]: numpy.ndarray
In[49]: type(pd.Categorical([1])._levels)
Out[49]: pandas.core.index.Int64Index
```

Internally, `_code` is mutable (at least in `__set_item__()`) , but `_levels` is always replaced, so this fits the ndarray vs index.