如何计算DataFrame中多组Process起止时间差并生成新DataFrame?
解决方案:计算多组流程耗时并生成新DataFrame
没问题,这种批量处理时序数据的场景我经常遇到,完全可以用Pandas的内置功能轻松实现,不用写复杂的逻辑。下面我分步骤给你讲清楚怎么操作:
关键前提:确保时间列是datetime类型
首先要注意,如果你的"Process-Starts"和"Process-Ends"列是字符串格式,直接做减法会报错。所以第一步必须把这些列转换为Pandas的datetime类型:
import pandas as pd # 假设你的原始DataFrame名为original_df for col in original_df.columns: # 匹配所有以-Starts或-Ends结尾的列 if col.endswith(('-Starts', '-Ends')): # 转换为datetime类型,如果你的时间格式特殊,可以加format参数,比如format='%Y-%m-%d %H:%M:%S' original_df[col] = pd.to_datetime(original_df[col], errors='coerce')
errors='coerce'会把无法转换的内容变成NaT(缺失时间值),方便后续排查问题。
批量计算流程耗时并生成新DataFrame
假设你的30组列名是有规律的(比如Process1-Starts、Process1-Ends、Process2-Starts...),我们可以通过提取流程名称前缀来批量处理:
# 提取所有唯一的流程名称(比如从列名中拆分出Process1、Process2...) process_names = sorted(set(col.split('-')[0] for col in original_df.columns if '-' in col)) # 创建空的新DataFrame用于存储结果 process_time_df = pd.DataFrame() # 循环计算每组的流程耗时 for process in process_names: start_col = f"{process}-Starts" end_col = f"{process}-Ends" # 计算耗时,结果是timedelta类型(比如00:30:00表示30分钟) process_time_df[f"{process}-Time"] = original_df[end_col] - original_df[start_col] # 可选:如果需要把耗时转成数值类型(比如分钟数),可以用下面的代码 # for process in process_names: # start_col = f"{process}-Starts" # end_col = f"{process}-Ends" # process_time_df[f"{process}-Time_Minutes"] = (original_df[end_col] - original_df[start_col]).dt.total_seconds() / 60
如果列名没有规律怎么办?
如果你的列名是类似Start1、End1、Start2、End2这种格式,只需要调整流程名称的生成逻辑即可:
# 直接生成30组流程标识 process_names = [f"Process{i}" for i in range(1, 31)] for idx, process in enumerate(process_names, 1): start_col = f"Start{idx}" end_col = f"End{idx}" process_time_df[f"{process}-Time"] = original_df[end_col] - original_df[start_col]
测试示例
给你一个小的测试代码,你可以先跑通再套用到自己的数据集上:
# 模拟原始数据 data = { "Process1-Starts": ["2024-01-01 09:00:00", "2024-01-02 10:00:00"], "Process1-Ends": ["2024-01-01 09:30:00", "2024-01-02 10:45:00"], "Process2-Starts": ["2024-01-01 11:00:00", "2024-01-02 12:00:00"], "Process2-Ends": ["2024-01-01 11:15:00", "2024-01-02 12:30:00"] } original_df = pd.DataFrame(data) # 转换时间列 for col in original_df.columns: if col.endswith(('-Starts', '-Ends')): original_df[col] = pd.to_datetime(original_df[col]) # 生成耗时DF process_names = sorted(set(col.split('-')[0] for col in original_df.columns)) process_time_df = pd.DataFrame() for p in process_names: process_time_df[f"{p}-Time"] = original_df[f"{p}-Ends"] - original_df[f"{p}-Starts"] print(process_time_df)
输出结果会是:
Process1-Time Process2-Time 0 00:30:00 00:15:00 1 00:45:00 00:30:00
常见问题排查
如果之前的代码失败,大概率是这几个原因:
- 时间列没转成
datetime类型,导致字符串减法报错; - 列名拼写不一致(比如大小写、多了空格),导致找不到对应的列;
- 存在缺失值,导致计算结果出现
NaT,可以用process_time_df.dropna()或者original_df.fillna()处理。
内容的提问来源于stack exchange,提问作者Student17
相关产品推荐
相关产品推荐

