基于Pandas的DataFrame时长拆分规则处理需求
问题说明
现有如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame() df['number'] = (651,651,651,4267,4267,4267,4267,4267,4267,4267,8806,8806,8806,6841,6841,6841,6841) df['name']=('Alex','Alex','Alex','Ankit','Ankit','Ankit','Ankit','Ankit','Ankit','Ankit','Abhishek','Abhishek','Abhishek','Blake','Blake','Blake','Blake') df['hours']=(8.25,7.5,7.5,7.5,14,12,15,11,6.5,14,15,15,13.5,8,8,8,8) df['loc']=('Nar','SCC','RSL','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNI','UNI','UNI','UNKING','UNKING','UNKING','UNKING')
需要按以下规则拆分每行数据:
- 若
hours在10到12之间(含边界):- 当前行
hours改为10 - 新增一行和当前行其他数据完全相同的记录,
hours填原时长减10的剩余值
- 当前行
- 若
hours大于12:- 当前行
hours改为10 - 新增一行
hours=2的同数据记录 - 再新增一行
hours填原时长减12剩余值的同数据记录
- 当前行
hours小于10的行直接保留原样
实现代码
import pandas as pd # 初始化原始DataFrame df = pd.DataFrame() df['number'] = (651,651,651,4267,4267,4267,4267,4267,4267,4267,8806,8806,8806,6841,6841,6841,6841) df['name']=('Alex','Alex','Alex','Ankit','Ankit','Ankit','Ankit','Ankit','Ankit','Ankit','Abhishek','Abhishek','Abhishek','Blake','Blake','Blake','Blake') df['hours']=(8.25,7.5,7.5,7.5,14,12,15,11,6.5,14,15,15,13.5,8,8,8,8) df['loc']=('Nar','SCC','RSL','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNIT-C','UNI','UNI','UNI','UNKING','UNKING','UNKING','UNKING') # 用来存拆分后的所有行数据 split_rows = [] # 逐行处理原始数据 for _, row in df.iterrows(): current_hours = row['hours'] # 提取除hours外的其他数据,作为拆分后新行的基础 base_data = row.drop('hours').to_dict() if 10 <= current_hours <= 12: # 第一条:hours设为10 split_rows.append({**base_data, 'hours': 10}) # 第二条:剩余时长 split_rows.append({**base_data, 'hours': current_hours - 10}) elif current_hours > 12: # 第一条:hours=10 split_rows.append({**base_data, 'hours': 10}) # 第二条:hours=2 split_rows.append({**base_data, 'hours': 2}) # 第三条:剩余时长(原时长-12) split_rows.append({**base_data, 'hours': current_hours - 12}) else: # 时长小于10,直接保留原行 split_rows.append(row.to_dict()) # 把拆分后的列表转成DataFrame,重置索引 final_df = pd.DataFrame(split_rows).reset_index(drop=True) print(final_df)
代码解释
- 遍历处理:循环原始DataFrame的每一行,先拿到当前行的
hours值,以及除hours外的其他字段数据; - 分支处理:根据
hours的范围,生成对应数量的拆分记录,把基础数据和新的hours值组合成新行; - 重组数据:把所有拆分后的行收集到列表里,再转成新的DataFrame,重置索引保证序号连续。
内容的提问来源于stack exchange,提问作者ds882
相关产品推荐
相关产品推荐

