悠悠楠杉
PandasDataFrame多列重塑:将宽格式数据转换为长格式的实用技巧
Pandas DataFrame多列重塑:将宽格式数据转换为长格式的实用技巧
在数据分析的实际工作中,经常会遇到数据以“宽格式”存储的情况——每一行代表一个观测单位,而多个变量被分散在不同的列中。例如,某份销售记录可能包含“产品A销量”、“产品B销量”、“产品A价格”、“产品B价格”等多个字段。这种结构虽然直观,却不利于后续的统计建模或可视化分析。此时,将宽格式数据转换为“长格式”就显得尤为重要。
Pandas 提供了强大的 melt() 和 wide_to_long() 函数来实现这一转换,尤其适用于多列数据的重塑操作。掌握这些工具,不仅能提升数据清洗效率,还能让分析流程更加清晰、可复用。
假设我们有一份学生成绩表,包含语文、数学、英语三门科目的成绩和对应的学习时间:
python
import pandas as pd
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五'],
'语文分数': [85, 90, 78],
'数学分数': [92, 88, 84],
'英语分数': [76, 95, 89],
'语文时长': [2.5, 3.0, 2.0],
'数学时长': [3.0, 2.5, 3.5],
'英语时长': [2.0, 3.5, 2.8]
})
我们的目标是将“科目”作为分类变量,把“分数”和“时长”分别拉成两列,形成一条条“学生-科目-分数-时长”的记录。这就需要对多列进行统一处理。
首先使用 pd.wide_to_long(),它特别适合结构规整、命名有规律的宽表。我们需要先调整列名,使其符合“变量名+后缀”的模式:
python
df.columns = ['姓名', '分数_语文', '分数_数学', '分数_英语', '时长_语文', '时长_数学', '时长_英语']
df_tidy = pd.wide_to_long(df,
stubnames=['分数', '时长'],
i='姓名',
j='科目',
sep='_',
suffix='\\w+')
这里 stubnames 指定了要拆分的变量前缀,“分数”和“时长”会自动与“语文”“数学”“英语”组合匹配;i 是不变的索引列,j 是新生成的类别列,sep 表示分隔符,suffix 匹配后缀内容。执行后,我们得到一个以“姓名+科目”为索引的长格式 DataFrame,每行对应一个学生的某一科目信息。
若列名不规则,或需要更灵活的控制,melt() 是更通用的选择。我们可以先手动构造标识列,再熔化数据:
python
dforiginal = df.copy()
dforiginal.columns = ['姓名', '语文分数', '数学分数', '英语分数', '语文时长', '数学时长', '英语时长']
分离出分数列和时长列
scorecols = ['语文分数', '数学分数', '英语分数']
timecols = ['语文时长', '数学时长', '英语时长']
dfmeltedscores = dforiginal[['姓名'] + scorecols].melt(
idvars='姓名', valuevars=scorecols, varname='科目分数', valuename='分数'
)
dfmeltedscores['科目'] = dfmeltedscores['科目分数'].str.replace('分数', '')
dfmeltedtimes = dforiginal[['姓名'] + timecols].melt(
idvars='姓名', valuevars=timecols, varname='科目时长', valuename='时长'
)
dfmeltedtimes['科目'] = dfmeltedtimes['科目时长'].str.replace('时长', '')
合并两个熔化后的表
result = pd.merge(dfmeltedscores[['姓名', '科目', '分数']],
dfmeltedtimes[['姓名', '科目', '时长']],
on=['姓名', '科目'])
这种方法虽然步骤较多,但逻辑清晰,适用于复杂场景。最终得到的结果是一个整洁的长格式数据集,便于按科目分组统计、绘制趋势图或输入机器学习模型。
值得注意的是,在实际操作中,列名的规范化往往是关键前提。善用字符串操作(如 str.split()、str.replace())能大幅提升数据重塑的效率。此外,重塑后建议重置索引并检查数据完整性,避免因缺失值或类型不一致影响后续分析。
掌握多列重塑技巧,意味着我们能更自由地驾驭数据形态,让原始杂乱的表格焕发结构之美。这不仅是技术操作,更是数据分析思维的体现——从“如何存”,走向“如何用”。
