Pandas因子化实现-factorize
在针对分类型数据的编码中,之前介绍过独热码get_dummies。本文介绍另一种方法:因子化。
因子化将pandas中object类型的数据映射称为一组数字,相同的标称型映射为相同的数字,在数据挖掘中常作为一种编码方式来应用。
因子化常用的方法:
- pandas.factorize()
- Series.factorize()
- Index.factorize()
函数说明
代码语言:javascript复制pandas.factorize(
values, # 待编码数据
sort=False, # 是否对数据中的唯一值排序
na_sentinel=- 1, # 缺失值编码为-1
size_hint=None # 哈希表可选大小,整型
)
返回值有两个:
- codes:因子化之后的编码列表,一般是ndarray
- uniques:原始数据中唯一值,一般是ndarray, Index, or Categorical
官网学习地址: https://pandas.pydata.org/docs/reference/api/pandas.factorize.html
针对数组
代码语言:javascript复制import pandas as pd
import numpy as np
代码语言:javascript复制codes, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b','a'])
代码语言:javascript复制codes
代码语言:javascript复制array([0, 0, 1, 2, 0, 1])
代码语言:javascript复制uniques
代码语言:javascript复制array(['b', 'a', 'c'], dtype=object)
参数sort的使用:对唯一值进行排序,排序后的顺序仍然和原来值出现的顺序保持一致
代码语言:javascript复制codes, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b','a'],sort=True)
代码语言:javascript复制codes
代码语言:javascript复制array([1, 1, 0, 2, 1, 0])
代码语言:javascript复制uniques
代码语言:javascript复制array(['a', 'b', 'c'], dtype=object)
缺失值的处理:
- 不会出现在唯一值列表中
- 在编码过程中编程-1
codes, uniques = pd.factorize(['b', 'b', 'a', 'c', None, 'b'])
代码语言:javascript复制codes
代码语言:javascript复制array([ 0, 0, 1, 2, -1, 0])
代码语言:javascript复制uniques
代码语言:javascript复制array(['b', 'a', 'c'], dtype=object)
针对Series
本身red、blue等取值就是无序的:
代码语言:javascript复制s = pd.Series(["red","blue","red","orange"])
s
代码语言:javascript复制0 red
1 blue
2 red
3 orange
dtype: object
代码语言:javascript复制codes, uniques = s.factorize()
代码语言:javascript复制codes
代码语言:javascript复制array([0, 1, 0, 2])
代码语言:javascript复制uniques
代码语言:javascript复制Index(['red', 'blue', 'orange'], dtype='object')
针对Categoricals分类型数据
代码语言:javascript复制cate = pd.Categorical(["b","a","b","c","b"], categories=["a","b","c"])
cate
代码语言:javascript复制['b', 'a', 'b', 'c', 'b']
Categories (3, object): ['a', 'b', 'c']
代码语言:javascript复制codes, uniques = pd.factorize(cate)
代码语言:javascript复制codes
代码语言:javascript复制array([0, 1, 0, 2, 0])
代码语言:javascript复制uniques
代码语言:javascript复制['b', 'a', 'c']
Categories (3, object): ['a', 'b', 'c']
此时uniques就是Categories类型的数据
缺陷
代码语言:javascript复制df = pd.DataFrame({"size":["M","XL","L","XS","S"]})
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
size | |
---|---|
0 | M |
1 | XL |
2 | L |
3 | XS |
4 | S |
s = df["size"]
s
代码语言:javascript复制0 M
1 XL
2 L
3 XS
4 S
Name: size, dtype: object
代码语言:javascript复制codes, uniques = s.factorize()
代码语言:javascript复制codes
代码语言:javascript复制array([0, 1, 2, 3, 4])
代码语言:javascript复制uniques
代码语言:javascript复制Index(['M', 'XL', 'L', 'XS', 'S'], dtype='object')
可以看到结果中codes数值的大小是根据uniques中取值的顺序来的。
也就说:因子化它没有考虑数据本身存在的潜在大小关系,只能根据数据本身的大小来编码。
但是根据衣服size大小的实际情况,我们想看到的编码效果为:可以看到不同尺寸代表实际大小的含义
代码语言:javascript复制XS-0
S-1
M-2
L-3
XL-4
代码语言:javascript复制df["code_f"] = codes
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
size | code_f | |
---|---|---|
0 | M | 0 |
1 | XL | 1 |
2 | L | 2 |
3 | XS | 3 |
4 | S | 4 |
通过map函数来直接映射,进行硬编码:
代码语言:javascript复制# 自定义编码
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; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
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 |