Replace category strings with integer codes. Assign each unique category an integer starting from 0. By hand, build a sorted-unique list, create a mapping dict, then look up each label. With pandas, astype('category').cat.codes produces the same codes because pandas assigns category codes in sorted alphabetical order.

By hand

With pandas

astype('category') converts the column to the pandas Categorical dtype and sets the category list in sorted order. .cat.codes returns the integer code for each element. The snapshot shows categories: ['bird', 'cat', 'dog'] so the code→label correspondence is immediately visible.

naive.py
labels = ['cat', 'dog', 'bird', 'dog', 'cat', 'bird']
unique = sorted(set(labels))
mapping = {}
for i, cat in enumerate(unique):
    mapping[cat] = i
result = []
for s in labels:
    result.append(mapping[s])
print('RESULT:', result)
library.py
import pandas as pd
from dalib.display import set_display
set_display()

labels = ['cat', 'dog', 'bird', 'dog', 'cat', 'bird']
df = pd.DataFrame({'c': labels})
s = df['c'].astype('category')
codes = s.cat.codes
result = codes.tolist()
print('categories:', s.cat.categories.tolist())
print('index:', codes.index.tolist())
print('dtype:', codes.dtype)
print('RESULT:', result)
categories: ['bird', 'cat', 'dog']
index: [0, 1, 2, 3, 4, 5]
dtype: int8
RESULT: [1, 2, 0, 2, 1, 0]

Implementation notes

  • pandas assigns category codes in sorted order, not first-seen order. The naive half uses sorted(set(labels)) to match — using insertion order (a plain dict walk) would produce different codes and break parity.
  • cat.codes dtype is int8; codes start at 0 for the first sorted category.
  • For explicit control over the code assignment (e.g. keeping a specific category as code 0), build a manual dict and use .map(dict) instead.
  • Cross-reference: encode-labels (ml-basics chapter) for one-hot and ordinal encoding alternatives.