如何正确转换DataFrame?基于ST、ED列拆分合并TYPE字段
时间区间拆分与TYPE聚合需求
需求说明
需要将输入的DataFrame按ST、ED列拆分时间区间,合并重叠/相邻区间后,把对应区间内的TYPE用逗号拼接,得到指定格式的输出DataFrame。
输入DataFrame
| ST | ED | TYPE |
|---|---|---|
| 201501 | 201503 | A |
| 201502 | 201504 | B |
| 201502 | 201505 | C |
输出DataFrame
| ST | ED | TYPE |
|---|---|---|
| 201501 | 201501 | A |
| 201502 | 201503 | A,B,C |
| 201504 | 201504 | B,C |
| 201505 | 201505 | C |
转换逻辑分析
转换后各区间对应的TYPE数量分别为1、3、2、1,对应原数据的时间区间拆分逻辑如下:
- 原数据A的区间
201501-201503拆分为201501-201501、201502-201503 - 原数据B的区间
201502-201504拆分为201502-201503、201504-201504 - 原数据C的区间
201502-201505拆分为201502-201503、201504-201504、201505-201505
将这些拆分后的区间合并为不重叠的连续区间,再把每个合并后区间内的所有TYPE拼接,就得到最终输出。
代码实现
import pandas as pd # 构建输入DataFrame df = pd.DataFrame({ 'ST': ['201501', '201502', '201502'], 'ED': ['201503', '201504', '201505'], 'TYPE': ['A', 'B', 'C'] }) # 将时间列转为整数,方便区间判断 df['ST'] = df['ST'].astype(int) df['ED'] = df['ED'].astype(int) # 提取所有关键时间点并排序 time_points = sorted(set(df['ST'].tolist() + df['ED'].tolist())) # 生成所有需要判断的独立区间段 intervals = [] for i in range(len(time_points)-1): start = time_points[i] end = time_points[i+1] intervals.append((start, start)) # 处理中间间隔的区间(如果有的话) if start + 1 <= end - 1: intervals.append((start+1, end-1)) intervals.append((end, end)) # 去重并重新排序区间 intervals = sorted(list(set(intervals))) # 匹配每个区间对应的TYPE result = [] for st, ed in intervals: # 筛选出与当前区间有重叠的原数据行 match_mask = (df['ST'] <= ed) & (df['ED'] >= st) matched_types = ','.join(df.loc[match_mask, 'TYPE'].tolist()) if matched_types: result.append({ 'ST': str(st), 'ED': str(ed), 'TYPE': matched_types }) # 转换为DataFrame并整理格式 result_df = pd.DataFrame(result).drop_duplicates().reset_index(drop=True) # 按照输出要求的顺序筛选行 final_df = result_df[result_df['ST'].isin(['201501','201502','201504','201505'])].reset_index(drop=True) print(final_df)
内容的提问来源于stack exchange,提问作者0in
相关产品推荐
相关产品推荐

