# Reg. Pandas factorize()

-Hi Experts-

I just read about factorise() function in Pandas. Using this I'm able to encode (enumerate) my string values into numbers. But, now I'm not able to understand what numbers corresponds to what string.

Ex.

df['product_name'] # Ex. A, B, C

df['product_name'] = df['product_name'].factorize()[0]
df['product_name'] # Ex. 0, 1, 2


Just illustration, not actual o/p -

A - 0
B - 1
C - 2


-Curious newbie :)

From the documnetation

Encode the object as an enumerated type or categorical variable.

This method is useful for obtaining a numeric representation of an array when all that matters is identifying distinct values. factorize is available as both a top-level function pandas.factorize(), and as a method Series.factorize() and Index.factorize().

The examples section goes on to show that the output of the factorize method actually returns two things:

1. labels - referring to the new values for each of your classes
2. uniques - essentially the mapping back to your original labels

df['product_name'] = df['product_name'].factorize()[0]


The part at the end: [0] means you are only taking the labels, throwing away the uniques that map back to your input.

If you keep both by making the same line:

df['product_name'], mapping = df['product_name'].factorize()


You could now do the rest of your work and end up with a results column full with the factorised output, you can use this line to get the original values back from those factorized labels:

mapped_back_to_product_name = mapping.take(results)


I suggest reading the documentation to get more information on how best to use the method :-)

Alternatively you can make use of categorical dtype in Pandas.

Demo:

Source DF:

In [108]: df
Out[108]:
product_name
0           AA
1           BB
2           AA
3           CC
4           BB
5           AA


first convert the string column product_name into category dtype:

In [109]: df['product_name'] = df['product_name'].astype('category')

In [110]: df
Out[110]:
product_name
0           AA
1           BB
2           AA
3           CC
4           BB
5           AA

In [111]: df.dtypes
Out[111]:
product_name    category
dtype: object


In [113]: df['product_name'].cat.codes
Out[113]:
0    0
1    1
2    0
3    2
4    1
5    0
dtype: int8


and to categories:

In [114]: df['product_name']
Out[114]:
0    AA
1    BB
2    AA
3    CC
4    BB
5    AA
Name: product_name, dtype: category
Categories (3, object): [AA, BB, CC]


@n1k31t4 has explained well. I just want to add that, by using sort=True parameter you can make sure that the labeling is done alphabetically which makes it easy to find out the corresponding labels and factorized classes.

Example from the documentation:

>>> labels, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'], sort=True)
>>> labels
array([1, 1, 0, 2, 1])
>>> uniques
array(['a', 'b', 'c'], dtype=object)