如何在DataFrame差异矩阵中将时间差转换为十进制数值
解决考勤时间差矩阵转十进制小时正负值的问题
你生成的差异矩阵本质是numpy timedelta64类型数组,没法直接用Pandas的dt访问器(dt仅支持Series/DataFrame),所以之前的total_seconds()方法直接用不了。这里给两种可行的转换方案:
方案1:转成Pandas DataFrame后批量处理
先把numpy数组包装成DataFrame,再用applymap遍历每个时间差元素完成转换:
import pandas as pd from datetime import datetime import numpy as np # 原始考勤数据 employees = [('GILL', datetime(2022,12,1,6,40,0), datetime(2022,12,1,14,30,0)), ('BOB', datetime(2022,12,1,6,0,0), datetime(2022,12,1,14,10,0)), ('TOBY', datetime(2022,12,1,14,0,0), datetime(2022,12,1,22,30,0))] labels = ['name', 'clockin', 'clockout'] df = pd.DataFrame.from_records(employees, columns=labels) # 构建时间差矩阵数组 arr = df['clockin'].values - df['clockin'].values[:, None] # 转换为十进制小时矩阵 diff_df = pd.DataFrame(arr, columns=df['name']) diff_hours = diff_df.applymap(lambda td: round(td.total_seconds() / 3600, 2)) # 合并员工姓名列得到最终结果 result = pd.concat([df['name'], diff_hours], axis=1) print(result)
方案2:直接用numpy操作数组(效率更高)
numpy的timedelta64可以直接转成总秒数,再计算为小时,适合数据量较大的场景:
# 直接将numpy时间差数组转为保留两位小数的小时数 arr_hours = np.round(arr.astype('timedelta64[s]') / 3600, 2) # 构建最终结果DataFrame result = pd.concat([df['name'], pd.DataFrame(arr_hours, columns=df['name'])], axis=1) print(result)
转换后效果
两种方案都会得到直观的正负小时数矩阵:
| name | GILL | BOB | TOBY | |
|---|---|---|---|---|
| 0 | GILL | 0.0 | -0.67 | 7.33 |
| 1 | BOB | 0.67 | 0.0 | 8.0 |
| 2 | TOBY | -7.33 | -8.0 | 0.0 |
数值含义:
- 正值:当前行员工比列员工晚打卡(比如BOB比GILL晚40分钟,即0.67小时)
- 负值:当前行员工比列员工早打卡(比如GILL比BOB早40分钟,即-0.67小时)
内容的提问来源于stack exchange,提问作者xtian
相关产品推荐
相关产品推荐

