Pandas pd.factorize() 函数
pd.factorize() 是 Pandas 库中用于编码分类变量的函数。它将分类数据转换为整数编码,同时返回唯一值列表。
这是机器学习预处理中的常用技术,将文本类别转换为数值,便于算法处理。与独热编码(pd.get_dummies())不同,因子化编码不会增加数据维度。
单词释义: factorize 意为"因子化",在这里指将分类变量转换为数值因子(整数编码)。
基本语法与参数
pd.factorize() 是 Pandas 库的顶级函数,用于将分类变量编码为整数。
语法格式
pd.factorize(values, sort=False, na_sentinel=-1, size_hint=None)
参数说明
- 参数:
values- 类型: 数组-like 对象,如 Series、列表、数组等。
- 描述: 要进行编码的分类数据。
- 参数:
sort- 类型> 布尔值。
- 如果为
True,对唯一值进行排序后再编码。默认为False(按出现顺序编码)。
- 参数:
na_sentinel- 类型: 整数。
- 用于标记缺失值的整数。默认为
-1。如果设为None,缺失值会保持为 NaN。
函数说明
- 返回值: 返回一个元组 (codes, uniques),其中 codes 是编码后的整数数组,uniques 是唯一值数组。
- 效果: 将分类变量映射为从 0 开始的整数序列,每个唯一值对应一个整数。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 pd.factorize() 的用法。
示例 1:基础用法 - 编码分类变量
实例
import pandas as pd
import numpy as np
# 1. 创建分类数据
colors = pd.Series(['red', 'blue', 'green', 'red', 'blue', 'yellow'])
print("=== 原始分类数据 ===")
print(colors)
# 2. 使用 pd.factorize() 进行编码
codes, uniques = pd.factorize(colors)
print("\n=== pd.factorize() 编码结果 ===")
print(f"编码: {codes}") # 编码后的整数
print(f"唯一值: {uniques}") # 唯一值列表
print(f"类型: {type(codes)}")
import numpy as np
# 1. 创建分类数据
colors = pd.Series(['red', 'blue', 'green', 'red', 'blue', 'yellow'])
print("=== 原始分类数据 ===")
print(colors)
# 2. 使用 pd.factorize() 进行编码
codes, uniques = pd.factorize(colors)
print("\n=== pd.factorize() 编码结果 ===")
print(f"编码: {codes}") # 编码后的整数
print(f"唯一值: {uniques}") # 唯一值列表
print(f"类型: {type(codes)}")
运行结果预期:
=== 原始分类数据 === 0 red 1 blue 2 green 3 red 4 blue 5 yellow 原始数据中 'red' 出现 2 次,'blue' 出现 2 次,'green' 和 'yellow' 各出现 1 次。 按出现顺序分配编码: - 'red' -> 0 - 'blue' -> 1 - 'green' -> 2 - 'yellow' -> 3 === 编码: [0 1 2 0 1 3] === 唯一值数组: ['red' 'blue' 'green' 'yellow']
代码解析:
- 返回的 codes 是一个整数数组,每个原始值都被替换为对应的整数码。
- uniques 数组存储了所有唯一值,按编码的对应顺序排列。
- 默认按出现顺序分配编码(首次出现的值编码为 0)。
示例 2:sort 参数 - 对唯一值排序后编码
使用 sort=True 可以对唯一值排序后再编码,便于结果的可预测性。
实例
import pandas as pd
import numpy as np
# 创建分类数据
colors = pd.Series(['red', 'blue', 'green', 'red', 'blue', 'yellow'])
print("=== 原始数据 ===")
print(colors)
# 1. 不排序(默认)- 按出现顺序编码
codes_unsorted, uniques_unsorted = pd.factorize(colors, sort=False)
print("\n=== sort=False (默认) ===")
print(f"编码: {codes_unsorted}")
print(f"唯一值: {uniques_unsorted}")
# 2. 排序后编码 - 按字母顺序
codes_sorted, uniques_sorted = pd.factorize(colors, sort=True)
print("\n=== sort=True (按字母顺序) ===")
print(f"编码: {codes_sorted}")
print(f"唯一值: {uniques_sorted}")
# 3. 对数值排序
numbers = pd.Series([5, 2, 8, 5, 3, 2, 9])
codes_num, uniques_num = pd.factorize(numbers, sort=True)
print("\n=== 数值排序编码 ===")
print(f"编码: {codes_num}")
print(f"唯一值: {uniques_num}")
import numpy as np
# 创建分类数据
colors = pd.Series(['red', 'blue', 'green', 'red', 'blue', 'yellow'])
print("=== 原始数据 ===")
print(colors)
# 1. 不排序(默认)- 按出现顺序编码
codes_unsorted, uniques_unsorted = pd.factorize(colors, sort=False)
print("\n=== sort=False (默认) ===")
print(f"编码: {codes_unsorted}")
print(f"唯一值: {uniques_unsorted}")
# 2. 排序后编码 - 按字母顺序
codes_sorted, uniques_sorted = pd.factorize(colors, sort=True)
print("\n=== sort=True (按字母顺序) ===")
print(f"编码: {codes_sorted}")
print(f"唯一值: {uniques_sorted}")
# 3. 对数值排序
numbers = pd.Series([5, 2, 8, 5, 3, 2, 9])
codes_num, uniques_num = pd.factorize(numbers, sort=True)
print("\n=== 数值排序编码 ===")
print(f"编码: {codes_num}")
print(f"唯一值: {uniques_num}")
运行结果预期:
=== 原始数据 === 0 red 1 blue 2 green 3 red 4 blue 5 yellow === sort=False (默认) === 编码: [0 1 2 0 1 3] 唯一值: ['red' 'blue' 'green' 'yellow'] === sort=True (按字母顺序) === 编码: [2 0 1 2 0 3] 唯一值: ['blue' 'green', 'red', 'yellow'] 按字母顺序排列:blue, green, red, yellow - blue -> 0 - green -> 1 - red -> 2 - yellow -> 3 === 数值排序编码 === 编码: [2 0 3 2 1 0 4] 唯一值: [2, 3, 5, 8, 9] 按数值排序:2, 3, 5, 8, 9 - 2 -> 0 - 3 -> 1 - 5 -> 2 - 8 -> 3 - 9 -> 4
代码解析:
sort=True对唯一值进行排序后再编码,编码顺序是确定的可预测的。- 这在需要结果可复现的情况下很有用。
示例 3:处理缺失值
na_sentinel 参数用于控制缺失值的处理方式。
实例
import pandas as pd
import numpy as np
# 1. 包含缺失值的数据
data = pd.Series(['a', 'b', np.nan, 'a', None, 'c', 'b'])
print("=== 包含缺失值的数据 ===")
print(data)
# 2. 默认行为(缺失值 → -1)
codes_default, uniques_default = pd.factorize(data)
print("\n=== 默认处理(缺失值 = -1)===")
print(f"编码: {codes_default}")
print(f"唯一值: {uniques_default}")
# 3. 自定义缺失值编码(模拟 na_sentinel=-999)
codes_custom = np.where(codes_default == -1, -999, codes_default)
print("\n=== 自定义缺失值编码(-999)===")
print(f"编码: {codes_custom}")
# 4. 保持 NaN(模拟 na_sentinel=None)
codes_nan = codes_default.astype('float')
codes_nan[codes_nan == -1] = np.nan
print("\n=== 保持 NaN ===")
print(f"编码: {codes_nan}")
print(f"编码类型: {type(codes_nan[2])}")
import numpy as np
# 1. 包含缺失值的数据
data = pd.Series(['a', 'b', np.nan, 'a', None, 'c', 'b'])
print("=== 包含缺失值的数据 ===")
print(data)
# 2. 默认行为(缺失值 → -1)
codes_default, uniques_default = pd.factorize(data)
print("\n=== 默认处理(缺失值 = -1)===")
print(f"编码: {codes_default}")
print(f"唯一值: {uniques_default}")
# 3. 自定义缺失值编码(模拟 na_sentinel=-999)
codes_custom = np.where(codes_default == -1, -999, codes_default)
print("\n=== 自定义缺失值编码(-999)===")
print(f"编码: {codes_custom}")
# 4. 保持 NaN(模拟 na_sentinel=None)
codes_nan = codes_default.astype('float')
codes_nan[codes_nan == -1] = np.nan
print("\n=== 保持 NaN ===")
print(f"编码: {codes_nan}")
print(f"编码类型: {type(codes_nan[2])}")
运行结果预期:
=== 包含缺失值的数据 === 0 a 1 b 2 NaN 3 a 4 None 5 c 6 b dtype: object === 默认处理(缺失值 = -1)=== 编码: [ 0 1 -1 0 -1 2 1] 唯一值: Index(['a', 'b', 'c'], dtype='object') === 自定义缺失值编码(-999)=== 编码: [ 0 1 -999 0 -999 2 1] === 保持 NaN === 编码: [ 0. 1. nan 0. nan 2. 1.] 编码类型: <class 'numpy.float64'>
示例 4:在机器学习中的应用
因子化编码在机器学习预处理中非常实用,特别是对于高基数分类变量。
实例
import pandas as pd
# 1. 创建包含分类变量的 DataFrame
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank'],
'city': ['Beijing', 'Shanghai', 'Beijing', 'Guangzhou', 'Shanghai', 'Beijing'],
'department': ['Sales', 'Engineering', 'Sales', 'HR', 'Engineering', 'Sales']
})
print("=== 原始 DataFrame ===")
print(df)
# 2. 对分类列进行因子化编码
# 创建一个映射字典
city_codes, city_uniques = pd.factorize(df['city'])
dept_codes, dept_uniques = pd.factorize(df['department'])
print("\n=== 因子化编码结果 ===")
print(f"city 编码: {city_codes.tolist()}")
print(f"city 唯一值: {city_uniques}")
print(f"department 编码: {dept_codes.tolist()}")
print(f"department 唯一值: {dept_uniques}")
# 3. 创建编码后的 DataFrame
df_encoded = df.copy()
df_encoded['city_encoded'] = city_codes
df_encoded['dept_encoded'] = dept_codes
print("\n=== 编码后的 DataFrame ===")
print(df_encoded)
# 4. 使用映射字典进行新数据编码
print("\n=== 映射字典 ===")
city_mapping = dict(zip(city_uniques, range(len(city_uniques))))
print(f"city 映射: {city_mapping}")
# 对新数据进行编码
new_cities = pd.Series(['Beijing', 'Shanghai', 'Shenzhen'])
new_codes = new_cities.map(city_mapping)
print(f"\n新数据编码: {new_codes.tolist()}")
# 1. 创建包含分类变量的 DataFrame
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank'],
'city': ['Beijing', 'Shanghai', 'Beijing', 'Guangzhou', 'Shanghai', 'Beijing'],
'department': ['Sales', 'Engineering', 'Sales', 'HR', 'Engineering', 'Sales']
})
print("=== 原始 DataFrame ===")
print(df)
# 2. 对分类列进行因子化编码
# 创建一个映射字典
city_codes, city_uniques = pd.factorize(df['city'])
dept_codes, dept_uniques = pd.factorize(df['department'])
print("\n=== 因子化编码结果 ===")
print(f"city 编码: {city_codes.tolist()}")
print(f"city 唯一值: {city_uniques}")
print(f"department 编码: {dept_codes.tolist()}")
print(f"department 唯一值: {dept_uniques}")
# 3. 创建编码后的 DataFrame
df_encoded = df.copy()
df_encoded['city_encoded'] = city_codes
df_encoded['dept_encoded'] = dept_codes
print("\n=== 编码后的 DataFrame ===")
print(df_encoded)
# 4. 使用映射字典进行新数据编码
print("\n=== 映射字典 ===")
city_mapping = dict(zip(city_uniques, range(len(city_uniques))))
print(f"city 映射: {city_mapping}")
# 对新数据进行编码
new_cities = pd.Series(['Beijing', 'Shanghai', 'Shenzhen'])
new_codes = new_cities.map(city_mapping)
print(f"\n新数据编码: {new_codes.tolist()}")
运行结果预期:
=== 原始 DataFrame ===
name city department
0 Alice Beijing Sales
1 Bob Shanghai Engineering
2 Charlie Beijing Sales
3 Diana Guangzhou HR
4 eve Shanghai Engineering
5 Frank Beijing Sales
=== 因子化编码结果 ===
city 编码: [0 1 0 2 1 0]
city 唯一值: ['Beijing' 'Shanghai' 'Guangzhou']
department 编码: [0 1 0 2 1 0]
department 唯一值: ['Sales' 'Engineering' 'HR']
=== 编码后的 DataFrame ===
name city department city_encoded dept_encoded
0 Alice Beijing Sales 0 0
1 Bob Shanghai Engineering 1 1
2 Charlie Beijing Sales 0 0
3 Diana Guangzhou HR 2 2
4 Eve Shanghai Engineering 1 1
5 Frank Beijing Sales 0 0
=== 映射字典 ===
city 映射: {'Beijing': 0, 'Shanghai': 1, 'Guangzhou': 2}
代码解析:
pd.factorize()返回元组,可以直接解包获取编码和唯一值。- 创建映射字典后,可以对新数据进行相同的编码,便于机器学习模型推理。
- 因子化编码不会增加数据维度,适合处理高基数分类变量。
提示:
pd.factorize()适合处理有序或无序的分类变量。如果需要独热编码(用于逻辑回归等算法),请使用pd.get_dummies()函数。

Pandas 常用函数