Pandas实现因子化

2023-08-25 11:40:12 浏览数 (1)

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
代码语言:javascript复制
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

代码语言:javascript复制
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

0 人点赞