一句话总结

本章补充 explode()(行展开)、get_dummies() / from_dummies()(哑变量)、factorize()(因子化)、cut() / qcut()(连续变量离散化)、transpose()(转置)、swapaxes()(轴交换)、swaplevel()(层级交换)等重塑常用工具。

1. explode() — 列表/元组列展开为多行

将单元格中的类列表数据展开,使每个元素单独成行,其他列自动复制。

基本语法

Series.explode(ignore_index=False)
DataFrame.explode(column, ignore_index=False)
参数说明
columnDataFrame 中要展开的列名(或列名列表)
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)

参数详解

参数说明
dataSeries、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  6

dtype 变化

转置后所有列都会变成同一 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'])

相关笔记