使用Pandas将单行数据拆分为多行并生成两新列的技术求助
Pandas实现单行转多行并填充新列的解决方案
Pandas完全可以实现你要的单行转多行并填充新列的需求,下面结合常见场景给出具体方案:
场景模拟(对应说明图逻辑)
假设你的原始数据格式如下(一行包含多组分数-科目对):
| ID | Name | Score1 | Subject1 | Score2 | Subject2 |
|---|---|---|---|---|---|
| 1 | 张三 | 90 | 数学 | 85 | 语文 |
| 2 | 李四 | 78 | 英语 | 92 | 物理 |
目标是转成每行对应一组分数-科目,新增Score和Subject两列:
| ID | Name | Score | Subject |
|---|---|---|---|
| 1 | 张三 | 90 | 数学 |
| 1 | 张三 | 85 | 语文 |
| 2 | 李四 | 78 | 英语 |
| 2 | 李四 | 92 | 物理 |
方案1:用wide_to_long(最简洁,适合列名带规律后缀)
当你的列名是前缀+数字的规律格式时,wide_to_long是最优选择:
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'ID': [1, 2], 'Name': ['张三', '李四'], 'Score1': [90, 78], 'Subject1': ['数学', '英语'], 'Score2': [85, 92], 'Subject2': ['语文', '物理'] }) # 转换格式 result = pd.wide_to_long( df, stubnames=['Score', 'Subject'], # 要保留的列前缀 i=['ID', 'Name'], # 作为分组标识的列(不参与拆分) j='temp_col', # 生成的临时后缀列名 sep='' # 列名中前缀和数字的分隔符(这里无分隔符) ).reset_index(drop=True) # 去掉临时列并重置索引
方案2:用melt(更灵活,适配无规律列名)
如果你的列名没有统一的数字后缀,或者需要更灵活的匹配逻辑,可以用melt拆分后再合并:
import pandas as pd # 构造示例数据(同上) df = pd.DataFrame({ 'ID': [1, 2], 'Name': ['张三', '李四'], 'Score1': [90, 78], 'Subject1': ['数学', '英语'], 'Score2': [85, 92], 'Subject2': ['语文', '物理'] }) # 拆分分数列 score_df = df.melt( id_vars=['ID', 'Name'], value_vars=['Score1', 'Score2'], var_name='score_col', value_name='Score' ) # 拆分科目列 subject_df = df.melt( id_vars=['ID', 'Name'], value_vars=['Subject1', 'Subject2'], var_name='subject_col', value_name='Subject' ) # 提取列名中的数字后缀,用于匹配对应行 score_df['suffix'] = score_df['score_col'].str.extract('(\d+)') subject_df['suffix'] = subject_df['subject_col'].str.extract('(\d+)') # 合并结果并保留需要的列 result = pd.merge(score_df, subject_df, on=['ID', 'Name', 'suffix'])[['ID', 'Name', 'Score', 'Subject']]
方案3:用stack(适合多级列名场景)
如果你的原始数据列名是多级索引格式,或者可以转成多级索引,stack方法会更高效:
import pandas as pd # 构造示例数据并设置多级列名 df = pd.DataFrame({ ('ID', ''): [1, 2], ('Name', ''): ['张三', '李四'], ('Score', '1'): [90, 78], ('Subject', '1'): ['数学', '英语'], ('Score', '2'): [85, 92], ('Subject', '2'): ['语文', '物理'] }) # 堆叠多级列的第二层,转成多行 result = df.stack(level=1).reset_index(drop=True)
根据你的实际列名格式选择对应的方法即可,其中wide_to_long在列名有规律时最省心。
内容的提问来源于stack exchange,提问作者user111189
相关产品推荐
相关产品推荐

