基于列表特定值创建DataFrame:小学成绩表格转换需求
解决方案:用Pandas重塑扁平化成绩数据
我来帮你搞定这个数据格式转换的问题,用Python的Pandas就能轻松实现,比手动构建嵌套列表高效太多了:
步骤1:准备数据(假设已导入合并为单列Series)
首先假设你已经把Excel合并后的列加载成了Pandas的Series,比如叫flat_data。原数据开头的score是无关表头,先把它去掉:
import pandas as pd import numpy as np # 模拟你的合并后数据(实际替换成你导入的列即可) flat_data = pd.Series(['score', 'NameA', 'test1', '10', 'test2', '23', 'test4', '15', 'NameB', 'test1', '10', 'test3', '17']) # 移除第一个无关的'score'元素 flat_data = flat_data[1:]
步骤2:识别学生分组
我们需要把每个学生的成绩片段归为一组,先标记所有学生名字的位置,再用累加生成组ID:
# 标记哪些元素是学生名字(假设名字都以'Name'开头,可根据实际调整判断逻辑) is_name = flat_data.str.startswith('Name') # 生成每个元素对应的组ID(每个学生对应一个组) group_ids = is_name.cumsum()
步骤3:分组转换为键值对字典
对每个学生组,把testX和对应成绩配对成键值对,学生名字作为索引:
# 定义处理单个学生组的函数 def process_group(group): # 组的第一个元素是学生名字 name = group.iloc[0] # 剩下的元素两两配对:testX -> 成绩 score_dict = dict(zip(group.iloc[1::2], group.iloc[2::2])) # 把字符串成绩转为数值类型 for k in score_dict: score_dict[k] = int(score_dict[k]) return pd.Series(score_dict, name=name) # 分组处理所有数据 result_dfs = flat_data.groupby(group_ids).apply(process_group)
步骤4:整理为最终宽格式表格
最后把结果转成标准表格,缺失的测试项自动用NaN填充:
# 调整结构为学生行、测试列的格式 final_df = result_dfs.unstack().T # 把列名改为首字母大写的格式(比如Test1代替test1) final_df.columns = final_df.columns.str.capitalize() # 把空值替换为显示友好的'NaN' final_df = final_df.replace(np.nan, 'NaN') print(final_df)
运行后会得到和你期望完全一致的表格:
Test1 Test2 Test3 Test4 NameA 10 23 NaN 15 NameB 10 NaN 17 NaN
关键思路说明
- 用
cumsum()分组:通过标记学生名字的位置,累加生成组ID,自动把每个学生的所有成绩片段归为一组 - 两两配对键值:利用Python的
zip()函数,把组内从第二个元素开始的奇数位(testX)和偶数位(成绩)配对成字典,完美对应每个测试的成绩 - Pandas自动补空:转成DataFrame时,Pandas会自动为缺失的测试列填充NaN,无需手动处理
如果你的学生名字不是以'Name'开头,只需要调整is_name的判断逻辑即可,比如用flat_data.str.contains('你的名字匹配规则')来适配实际格式。
内容的提问来源于stack exchange,提问作者Maartenk
相关产品推荐
相关产品推荐

