Преобразование категориальных данных в фреймворк pandas


103

У меня есть фрейм данных с этим типом данных (слишком много столбцов):

col1        int64
col2        int64
col3        category
col4        category
col5        category

Столбцы выглядят так:

Name: col3, dtype: category
Categories (8, object): [B, C, E, G, H, N, S, W]

Я хочу преобразовать все значения в столбцах в целые числа следующим образом:

[1, 2, 3, 4, 5, 6, 7, 8]

Я решил это для одного столбца следующим образом:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes

Теперь у меня есть две колонки в моей dataframe - старые col3и новые , cи нужно отказаться от старых колонок.

Это плохая практика. Это работает, но в моем фреймворке много столбцов, и я не хочу делать это вручную.

Как вообще этот питоник и просто хитро?

Ответы:


166

Во- первых, чтобы преобразовать категорический столбец его числовые коды, вы можете сделать это легче с: dataframe['c'].cat.codes.
Кроме того, можно автоматически выбрать все столбцы с определенным dtype в кадре данных с помощью select_dtypes. Таким образом, вы можете применить вышеуказанную операцию к нескольким автоматически выбранным столбцам.

Сначала создайте пример фрейма данных:

In [75]: df = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})

In [76]: df['col2'] = df['col2'].astype('category')

In [77]: df['col3'] = df['col3'].astype('category')

In [78]: df.dtypes
Out[78]:
col1       int64
col2    category
col3    category
dtype: object

Затем, используя select_dtypesдля выбора столбцов, а затем применяя .cat.codesк каждому из этих столбцов, вы можете получить следующий результат:

In [80]: cat_columns = df.select_dtypes(['category']).columns

In [81]: cat_columns
Out[81]: Index([u'col2', u'col3'], dtype='object')

In [83]: df[cat_columns] = df[cat_columns].apply(lambda x: x.cat.codes)

In [84]: df
Out[84]:
   col1  col2  col3
0     1     0     0
1     2     1     1
2     3     2     0
3     4     0     1
4     5     1     1

14
есть ли простой способ получить соответствие между кодом категории и строковыми значениями категории?
Allan Ruin

5
Вы можете использовать: df['col2'].cat.categoriesнапример.
ogrisel 08

13
Обращаем внимание всех, кто обеспокоен тем, что это будет NaNуникальная карта для-1
quietContest

2
Обожаю 2 лайнера;)
Jose A

Обратите внимание: если категория упорядочена (порядковый номер), то возвращаемые числовые коды cat.codesНЕ могут быть теми, которые вы видите в серии!
Паулперри


20

Если вы беспокоились только о том, что вы создаете дополнительный столбец и удаляете его позже, просто сначала используйте новый столбец.

dataframe = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
dataframe.col3 = pd.Categorical.from_array(dataframe.col3).codes

Вы сделали. Теперь, когда Categorical.from_arrayустарело, используйте Categoricalнапрямую

dataframe.col3 = pd.Categorical(dataframe.col3).codes

Если вам также требуется обратное сопоставление от индекса к метке, есть еще лучший способ для того же

dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()

проверьте ниже

print(dataframe)
print(mapping_index.get_loc("c"))

11

Здесь необходимо преобразовать несколько столбцов. Итак, я использовал один подход ...

for col_name in df.columns:
    if(df[col_name].dtype == 'object'):
        df[col_name]= df[col_name].astype('category')
        df[col_name] = df[col_name].cat.codes

Это преобразует все столбцы строкового / объектного типа в категориальные. Затем применяет коды к каждому типу категории.


3

Для преобразования категориальных данных в столбце C данных набора данных нам необходимо сделать следующее:

from sklearn.preprocessing import LabelEncoder 
labelencoder= LabelEncoder() #initializing an object of class LabelEncoder
data['C'] = labelencoder.fit_transform(data['C']) #fitting and transforming the desired categorical column.

2

То, что я делаю, я replaceценю.

Как это-

df['col'].replace(to_replace=['category_1', 'category_2', 'category_3'], value=[1, 2, 3], inplace=True)

Таким образом, если colстолбец имеет категориальные значения, они заменяются числовыми значениями.


1

@ Quickbeam2k1, см. Ниже -

dataset=pd.read_csv('Data2.csv')
np.set_printoptions(threshold=np.nan)
X = dataset.iloc[:,:].values

Использование sklearn введите описание изображения здесь

from sklearn.preprocessing import LabelEncoder
labelencoder_X=LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])

3
Почему ты просто не исправил свой предыдущий ответ? Удивительно, но fit_transformтеперь вы используете вместо transform_fitопределения labelencoder и исправили. Почему вы используете iloc[:,:]? это бесполезно. В чем причина изображения? Если вы хотите доказать мне и @theGtknerd, вы потерпели неудачу.
Quickbeam2k1

0

Для определенного столбца, если вас не волнует порядок, используйте этот

df['col1_num'] = df['col1'].apply(lambda x: np.where(df['col1'].unique()==x)[0][0])

Если вас интересует порядок, укажите их в виде списка и используйте этот

df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third'].index(x))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.