for i,e in enumerate(df.c2.unique()):
df.loc[df.c2 == e,'c3'] = i
можно заменить
df['c3'] = pd.Categorical(df['c2']).codes
Даже для этого небольшого DataFrame, используя Категорический является (около 4х) быстрее:
In [33]: %%timeit
...: for i,e in enumerate(df.c2.unique()):
df.loc[df.c2 == e,'c3'] = i
1000 loops, best of 3: 1.07 ms per loop
In [35]: %timeit pd.Categorical(df['c2']).codes
1000 loops, best of 3: 264 µs per loop
Улучшение скорости будет увеличиваться с количеством уникальных элементов в df['c2']
, поскольку относительная неэффективность Python for-loop
станет более очевидной при увеличении количества итераций.
Например, если
import string
import numpy as np
import pandas as pd
N = 10000
df = pd.DataFrame({'c1':np.arange(N),
'c2':np.random.choice(list(string.letters), size=N)})
затем с помощью Категориальные является (около 56x) быстрее:
In [53]: %%timeit
....: for i,e in enumerate(df.c2.unique()):
df.loc[df.c2 == e,'c3'] = i
10 loops, best of 3: 58.2 ms per loop
In [54]: %timeit df['c3'] = pd.Categorical(df['c2']).codes
1000 loops, best of 3: 1.04 ms per loop
Тесты выше, были сделаны с IPython's% timeit "волшебной функции".