将DataFrame中时分秒格式时长转换为分钟并拆分列
解决CSV时长列拆分与分钟转换的计算错误
原始数据与需求
原始CSV数据格式:
Day,Duration Mon,"S: 3h0s, P: 18m0s" Tues,"S: 3h0s, P: 18m0s" Wed,"S: 4h0s, P: 18m0s" Thurs,"S: 30h, P: 10m0s" Fri,"S: 15m, P: 3h0s"
需求:将Duration列拆分为S(min)和P(min)两列,统一转换为分钟单位,期望输出:
Day Duration S(min) P(min) 0 Mon S: 3h0s, P: 18m0s 180 18 1 Tues S: 3h0s, P: 18m0s 180 18 2 Wed S: 4h0s, P: 18m0s 240 18 3 Thur S: 30h0s, P: 10m0s 1800 10 4 Fri S: 15m, P: 3h0s 15 180
错误代码与问题
原处理代码:
import pandas as pd df = pd.read_csv("/file.csv") df["S(min)"] = df['Duration'].str.split(',').str[0] df["P(min)"] = df['Duration'].str.split(',').str[-1] df['S(min)'] = df['S(min)'].str.replace("S: ", '').str.replace("h", '*60').str.replace('m','*1').str.replace('s','*(1/60)').apply(eval) df['P(min)'] = df['P(min)'].str.replace("P: ", '').str.replace("h", '*60').str.replace('m','*1').str.replace('s','*(1/60)').apply(eval)
错误结果:
Day Duration S(min) P(min) 0 Mon S: 3h0s, P: 18m0s 30.0 3.000000 1 Tues S: 3h0s, P: 18m0s 30.0 3.000000 2 Wed S: 4h0s, P: 18m0s 40.0 3.000000 3 Thurs S: 30h, P: 10m0s 1800.0 1.666667 4 Fri S: 15m, P: 3h0s 15.0 30.000000
错误原因
直接字符替换会导致单位与后续数字拼接错误,比如3h0s会被替换成3*600*(1/60),实际计算为3*600/60=30,而非正确的3*60 + 0/60=180。这种方式无法区分数字与单位的边界,导致计算逻辑混乱。
正确解决方案
使用正则表达式精准匹配时长中的数字与对应单位,分别计算各单位对应的分钟数后累加:
import pandas as pd import re def convert_to_minutes(duration_str): # 匹配"数字+单位"的组合,支持h/m/s pattern = r'(\d+)([hms])' matches = re.findall(pattern, duration_str) total_min = 0 for num, unit in matches: num = int(num) if unit == 'h': total_min += num * 60 elif unit == 'm': total_min += num elif unit == 's': total_min += num / 60 return total_min # 读取CSV df = pd.read_csv("/file.csv") # 拆分S和P部分,去除多余空格与标识 df[["S_part", "P_part"]] = df['Duration'].str.split(',', expand=True) df["S_part"] = df["S_part"].str.replace("S: ", "").str.strip() df["P_part"] = df["P_part"].str.replace("P: ", "").str.strip() # 转换为分钟单位 df["S(min)"] = df["S_part"].apply(convert_to_minutes) df["P(min)"] = df["P_part"].apply(convert_to_minutes) # 清理中间列(可选) df = df.drop(["S_part", "P_part"], axis=1) # 输出结果 print(df)
代码说明
- 正则匹配:
r'(\d+)([hms])'可以精准提取每个时长片段的数字和单位,比如从3h0s中提取('3','h')和('0','s')。 - 单位转换:根据不同单位(小时/分钟/秒)分别转换为分钟后累加,确保计算逻辑正确。
- 数据清洗:拆分后去除多余的标识文本和空格,保证输入到转换函数的字符串格式干净。
运行后即可得到符合预期的结果。
内容的提问来源于stack exchange,提问作者user53526356
相关产品推荐
相关产品推荐

