OrdinalEncoder序数编码器的astype('category')实现形式
发布于 作者:苏南大叔 来源:程序如此灵动~
本文再次回顾一下序数编码器,以及它的另外一个使用astype('category')的实现形式。category终究是在做什么?有什么样的效果呢?

苏南大叔的“程序如此灵动”博客,这里讲述苏南大叔和计算机代码之间的故事。测试环境:python@3.12.3,pandas@2.2.2,numpy@1.26.4。
前文回顾
sklearn内置有两种编码器,分别是:LabelEncoder和OrdinalEncoder。参考文章:
本文涉及的是后者OrdinalEncoder序数编码器。在本文中,将使用dataframe的原生方式获得OrdinalEncoder序数编码器的同样效果。进而加深证明category类型的基本逻辑。
样本数据
import pandas as pd
df = pd.DataFrame({
's': ['su', '苏', 'SU', 'su', '南', '苏'],
'n': ['nan', '南', '苏', 'Nan', 'NAN', '南']})
print(df)输出:
s n
0 su nan
1 苏 南
2 SU 苏
3 su Nan
4 南 NAN
5 苏 南OrdinalEncoder
from sklearn import preprocessing
c = preprocessing.OrdinalEncoder().fit_transform(df)
print(c)
print(type(c))输出:
[[1. 2.]
[3. 3.]
[0. 4.]
[1. 1.]
[2. 0.]
[3. 3.]]
<class 'numpy.ndarray'>自定义算法
df2 = df.astype('category')
c = pd.DataFrame({col: df2[col].cat.codes for col in df2}, index=df2.index)
print(c)
print(type(c))输出:
s n
0 1 2
1 3 3
2 0 4
3 1 1
4 2 0
5 3 3
<class 'pandas.core.frame.DataFrame'>核心操作就是.astype('category')。和下面这篇文章里面的操作,有些类似:
关于for in遍历,这里可以参考文章:
为什么要category,对于存在大量重复数据的情况下,这样操作可以节约空间。但是,如果数据量不重复,并且数据比较少的情况下,使用.astype('category'),反而会稍微增大空间开销。
可以使用df.memory_usage()查看内存占用情况。统一一下结果
两者的数据的结果是一致的,但是表现形式上还是略有区别的。因此下面的代码对OrdinalEncoder的结果做了个转化,让两者看起来完全一致。
from sklearn import preprocessing
c = preprocessing.OrdinalEncoder().fit_transform(df)
c = pd.DataFrame(c,columns=['s','n']).astype(int)
print(c)
print(type(c))输出:
s n
0 1 2
1 3 3
2 0 4
3 1 1
4 2 0
5 3 3
<class 'pandas.core.frame.DataFrame'>
结语
OrdinalEncoder序数编码器的原理,就是:把所有的数据以列为单位,进行category化。然后它们的index值组合就是最终的编码的值组合。