Как сгенерировать столбец pandas DataFrame категориального из столбца string?

Я могу преобразовать столбец строки pandas в категориальный, но когда я пытаюсь вставить его в качестве нового столбца фрейма данных, он, похоже, преобразуется обратно в серию str:

train['LocationNFactor'] = pd.Categorical.from_array(train['LocationNormalized'])

>>> type(pd.Categorical.from_array(train['LocationNormalized']))
<class 'pandas.core.categorical.Categorical'>
# however it got converted back to...
>>> type(train['LocationNFactor'][2])
<type 'str'>
>>> train['LocationNFactor'][2]
'Hampshire'

предполагая, что это потому, что Categorical не сопоставляется с каким-либо numpy dtype; поэтому мне нужно преобразовать его в некоторый тип int и, таким образом, потерять ассоциацию уровней меток факторов? Каков самый элегантный обходной путь для хранения ассоциации меток levelsи сохранения возможности преобразования обратно? (просто храните как дикт, как здесь, и при необходимости вручную конвертировать?) Я думаю Categorical по-прежнему не является первоклассным типом данных для DataFrame, в отличие от Р.

(используя pandas 0.10.1, numpy 1.6.2, python 2.7.3-последние версии macports всего).

2 ответов


только обходной путь для панд pre-0.15 Я нашел следующее:

  • столбец должен быть преобразован в категориальный для классификатора, но numpy немедленно принудит уровни вернуться к int, потеряв факторную информацию
  • поэтому сохраните фактор в глобальной переменной вне фрейма данных

.

train_LocationNFactor = pd.Categorical.from_array(train['LocationNormalized']) # default order: alphabetical

train['LocationNFactor'] = train_LocationNFactor.labels # insert in dataframe

[UPDATE: pandas 0.15 + добавлена достойная поддержка Categorical]


метки уровни хранятся в объекте index.

  • чтобы преобразовать целочисленный массив в строковый массив: index[integer_array]
  • преобразование строкового массива в целочисленный массив: index.get_indexer(string_array)

вот пример:

In [56]:

c = pd.Categorical.from_array(['a', 'b', 'c', 'd', 'e'])

idx = c.levels

In [57]:

idx[[1,2,1,2,3]]

Out[57]:

Index([b, c, b, c, d], dtype=object)

In [58]:

idx.get_indexer(["a","c","d","e","a"])

Out[58]:

array([0, 2, 3, 4, 0])