一句话总结
本章补充
explode()(行展开)、get_dummies()/from_dummies()(哑变量)、factorize()(因子化)、cut()/qcut()(连续变量离散化)、transpose()(转置)、swapaxes()(轴交换)、swaplevel()(层级交换)等重塑常用工具。
1. explode() — 列表/元组列展开为多行
将单元格中的类列表数据展开,使每个元素单独成行,其他列自动复制。
基本语法
Series.explode(ignore_index=False)
DataFrame.explode(column, ignore_index=False)| 参数 | 说明 |
|---|---|
column | DataFrame 中要展开的列名(或列名列表) |
ignore_index | 是否重置索引,默认 False |
示例:单列展开
import pandas as pd
df = pd.DataFrame({
'order_id': [1, 2],
'items': [['apple', 'banana'], ['orange']],
'price': [5, 3]
})
df.explode('items')
# order_id items price
# 0 1 apple 5
# 0 1 banana 5
# 1 2 orange 3示例:多列同步展开
df2 = pd.DataFrame({
'id': [1, 2],
'x': [[1, 2], [3, 4]],
'y': [['a', 'b'], ['c', 'd']]
})
# 要求两列长度相同
df2.explode(['x', 'y'])
# id x y
# 0 1 1 a
# 0 1 2 b
# 1 2 3 c
# 1 2 4 d注意
- 若某些单元格是标量(非列表),会保持原值不展开。
- 空列表
[]展开后会得到NaN行(可通过dropna()移除)。
2. get_dummies() — 哑变量编码
将分类变量转换为 0/1 哑变量(One-Hot Encoding),常用于机器学习特征工程。
基本语法
pd.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False,
columns=None, sparse=False, drop_first=False, dtype=None)参数详解
| 参数 | 说明 |
|---|---|
data | Series、DataFrame 或类数组 |
prefix | 生成的列名前缀,如 prefix='city' → city_北京 |
prefix_sep | 前缀与类别之间的分隔符,默认 '_' |
dummy_na | 是否为 NaN 单独创建一列,默认 False |
columns | 指定要编码的列(仅 DataFrame 时有效),默认所有 object/category 列 |
drop_first | 是否删除第一个类别列(避免多重共线性),默认 False |
dtype | 输出列的数据类型,默认 np.uint8 |
示例:Series 编码
s = pd.Series(['北京', '上海', '北京', '广州'])
pd.get_dummies(s)
# 北京 上海 广州
# 0 1 0 0
# 1 0 1 0
# 2 1 0 0
# 3 0 0 1示例:DataFrame 编码
df = pd.DataFrame({
'name': ['A', 'B', 'C'],
'city': ['北京', '上海', '北京'],
'score': [80, 90, 85]
})
pd.get_dummies(df, columns=['city'], prefix='city')
# name score city_北京 city_上海
# 0 A 80 1 0
# 1 B 90 0 1
# 2 C 85 1 0示例:drop_first 与 dummy_na
pd.get_dummies(s, drop_first=True) # 少一列,避免共线性
pd.get_dummies(s, dummy_na=True) # 为 NaN 单独生成列示例:与 cut 配合
df['age_group'] = pd.cut(df['age'], bins=[0, 18, 35, 60, 100])
pd.get_dummies(df, columns=['age_group'])3. from_dummies() — 哑变量逆操作
pd.from_dummies() 将哑变量 DataFrame 还原为单个分类列(pandas 1.5+)。
基本语法
pd.from_dummies(data, sep=None, default_category=None)| 参数 | 说明 |
|---|---|
data | 哑变量 DataFrame |
sep | 列名前缀与类别间的分隔符,若设置则把列名中的类别提取出来 |
default_category | 所有哑变量均为 0 时,默认填充的类别 |
示例
dummies = pd.DataFrame({
'city_北京': [1, 0, 1],
'city_上海': [0, 1, 0]
})
pd.from_dummies(dummies, sep='_')
# city
# 0 北京
# 1 上海
# 2 北京4. factorize() — 因子化编码
将数组编码为整数标签(0, 1, 2…)和唯一值列表,是 get_dummies 的轻量替代。
基本语法
pd.factorize(values, sort=False, use_na_sentinel=True, size_hint=None)| 参数 | 说明 |
|---|---|
values | 一维序列 |
sort | 是否按唯一值排序后再编码 |
use_na_sentinel | 是否将 NaN 编码为 -1 |
示例
codes, uniques = pd.factorize(['a', 'b', 'a', 'c'])
print(codes) # [0 1 0 2]
print(uniques) # Index(['a', 'b', 'c'], dtype='object')示例:DataFrame 使用
df['city_code'], city_uniques = pd.factorize(df['city'])5. cut() / qcut() — 连续变量离散化
cut() — 等距分箱
pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3,
include_lowest=False, duplicates='raise', ordered=True)| 参数 | 说明 |
|---|---|
x | 一维数组/Series |
bins | 箱数(int)或边界数组(list) |
right | 区间是否右闭合,默认 True (a, b] |
labels | 箱的标签(需与箱数一致) |
retbins | 是否返回箱边界 |
include_lowest | 第一个区间是否包含左端点 |
ages = pd.Series([15, 25, 35, 45, 55, 65])
bins = [0, 18, 35, 60, 100]
labels = ['少年', '青年', '中年', '老年']
age_group = pd.cut(ages, bins=bins, labels=labels)
# 0 少年
# 1 青年
# 2 青年
# 3 中年
# 4 中年
# 5 老年qcut() — 等频分箱
pd.qcut(x, q, labels=None, retbins=False, precision=3, duplicates='raise')按分位数切分,每箱样本数大致相等。
scores = pd.Series([40, 55, 60, 70, 75, 80, 85, 95])
quartile = pd.qcut(scores, q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])对比
| 方法 | 分箱逻辑 | 适用场景 |
|---|---|---|
cut() | 按数值范围等距切分 | 年龄、温度等有固定含义的变量 |
qcut() | 按分位数等频切分 | 偏态分布、希望每组样本数均衡 |
与 get_dummies 组合
# 将连续变量离散化并哑变量编码 df['age_bin'] = pd.cut(df['age'], bins=3, labels=['young', 'mid', 'old']) df_dummies = pd.get_dummies(df, columns=['age_bin'])
6. transpose() / T — 转置
交换 DataFrame 的行与列(index ↔ columns)。
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['x', 'y', 'z'])
df.transpose() # 等价写法:df.T
# x y z
# A 1 2 3
# B 4 5 6dtype 变化
转置后所有列都会变成同一 dtype(通常
object),因为原各列 dtype 可能不同。
7. swapaxes() — 轴交换
交换指定轴的位置,作用于 index/columns 层级。
DataFrame.swapaxes(axis1, axis2, copy=None)# 对 DataFrame 而言,swapaxes(0, 1) 等价于 transpose()
df.swapaxes(0, 1)
# 多层索引时,swapaxes(0, 1) 与 T 效果相同但更灵活8. swaplevel() — 交换多层索引层级
仅作用于 MultiIndex,交换不同层级的顺序。
DataFrame.swaplevel(i=-2, j=-1, axis=0)
Series.swaplevel(i=-2, j=-1, axis=0)| 参数 | 说明 |
|---|---|
i, j | 要交换的层级位置(int)或名称(str),默认 -2 与 -1 |
axis | 对行索引(0)或列索引(1)操作 |
idx = pd.MultiIndex.from_product([['A', 'B'], [1, 2]])
df = pd.DataFrame(np.random.rand(4, 2), index=idx, columns=['x', 'y'])
# 交换行索引层级
df.swaplevel(0, 1)
df.swaplevel('first', 'second')9. 综合实战:重塑工具箱组合
# 原始长表
df_long = pd.DataFrame({
'id': [1, 1, 2, 2],
'variable': ['math', 'english', 'math', 'english'],
'value': [90, 85, 78, 92]
})
# 1) pivot 转宽表
wide = df_long.pivot(index='id', columns='variable', values='value')
# 2) 转置
wide_T = wide.T
# 3) 连续变量离散化 + 哑变量
df['value_group'] = pd.cut(df['value'], bins=3, labels=['低', '中', '高'])
dummies = pd.get_dummies(df, columns=['value_group'])
# 4) factorize 编码
df['id_code'], _ = pd.factorize(df['id'])