特征工程:Pandas实现因子化

167 阅读3分钟

公众号:尤而小屋
作者:Peter
编辑:Peter

大家好,我是Peter~

今天给大家分享的是关于特征工程的文章:Pandas因子化实现-factorize

在针对离散型数据的编码,之前介绍过独热码one-hot。本文介绍另一种方法:因子化

因子化是将Pandas中object类型的数据映射称为一组数字,相同的标称型映射为相同的数字,在数据挖掘中常作为一种编码方式来应用。

因子化常用的方法:

  • pandas.factorize()
  • Series.factorize()
  • Index.factorize()

函数说明

pandas.factorize(
    values,  # 待编码数据
    sort=False,   # 是否对数据中的唯一值排序
    na_sentinel=- 1,  # 缺失值编码为-1
    size_hint=None  # 哈希表可选大小,整型
)

返回值有两个:

  • codes:因子化之后的编码列表,一般是ndarray
  • uniques:原始数据中唯一值,一般是ndarray, Index, or Categorical

官网学习地址: pandas.pydata.org/docs/refere…

针对数组

import pandas as pd
import numpy as np
codes, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b','a'])
codes
array([0, 0, 1, 2, 0, 1])
uniques
array(['b', 'a', 'c'], dtype=object)

参数sort的使用:对唯一值进行排序,排序后的顺序仍然和原来值出现的顺序保持一致

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

缺失值的处理:

  • 不会出现在唯一值列表中

  • 在编码过程中编程-1

codes, uniques = pd.factorize(['b', 'b', 'a', 'c', None, 'b'])
codes
array([ 0,  0,  1,  2, -1,  0])
uniques
array(['b', 'a', 'c'], dtype=object)

针对Series

本身red、blue等取值就是无序的:

s = pd.Series(["red","blue","red","orange"])
s
0       red
1      blue
2       red
3    orange
dtype: object
codes, uniques = s.factorize()
codes
array([0, 1, 0, 2])
uniques
Index(['red', 'blue', 'orange'], dtype='object')

针对Categoricals分类型数据

cate = pd.Categorical(["b","a","b","c","b"], categories=["a","b","c"])
cate
['b', 'a', 'b', 'c', 'b']
Categories (3, object): ['a', 'b', 'c']
codes, uniques = pd.factorize(cate)
codes
array([0, 1, 0, 2, 0])
uniques
['b', 'a', 'c']
Categories (3, object): ['a', 'b', 'c']

此时uniques就是Categories类型的数据

缺陷

df = pd.DataFrame({"size":["M","XL","L","XS","S"]})
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
size
0 M
1 XL
2 L
3 XS
4 S
s = df["size"]
s
0     M
1    XL
2     L
3    XS
4     S
Name: size, dtype: object
codes, uniques = s.factorize()
codes
array([0, 1, 2, 3, 4])
uniques
Index(['M', 'XL', 'L', 'XS', 'S'], dtype='object')

可以看到结果中codes数值的大小是根据uniques中取值的顺序来的。

也就说:因子化它没有考虑数据本身存在的潜在大小关系,只能根据数据本身的大小来编码。

但是根据衣服size大小的实际情况,我们想看到的编码效果为:可以看到不同尺寸代表实际大小的含义

XS-0
S-1
M-2
L-3
XL-4
df["code_f"] = codes
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
size code_f
0 M 0
1 XL 1
2 L 2
3 XS 3
4 S 4

通过map函数来直接映射,进行硬编码:

# 自定义编码
dic = {"XS":0,"S":1,"M":2,"L":3,"XL":4}

# 编码映射
df["code_m"] = df["size"].map(dic)
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
size code_f code_m
0 M 0 2
1 XL 1 4
2 L 2 3
3 XS 3 0
4 S 4 1