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:
- labels - referring to the new values for each of your classes
- uniques - essentially the mapping back to your original labels
In your line of code:
df['product_name'] = df['product_name'].factorize()
The part at the end:
 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 :-)