修复 pandas 错误地将时间戳 hh:mm:ss 解释为 yyyy-dd-mmThh:mm:ss
Fix pandas wrongly interpretting timestamps hh:mm:ss into yyyy-dd-mmThh:mm:ss
我需要将 .xlsx sheet 导入到 pandas 中,其中有一列用于关联 activity 的处理时间。此列中的所有条目看起来都像这样:
01:20:34
12:22:30
25:01:02
155:20:56
这表示需要多少小时、分钟和秒。当我使用 pd.read_excel
时,pandas 正确解释了每个小于 24 小时的时间戳,并在前两种情况下按上述方式读取它们。另一方面,超过 24 小时(最后两个)的时间戳被转换为日期时间对象,它又看起来像这样:1900-01-02T14:58:03
而不是 62:58:03
。
有没有简单的解决方法?
我认为部分问题不在Python/Pandas,而在Excel。日期“1900-01-01”是 Excel 使用的基准日期,用数字“1”表示。您可以检查是否在单元格中写入“0”,然后将该单元格格式化为日期,您会得到“1900-01-00”,而“1”会得到“1900-01-01”。
因此,在导入到 pandas 之前尝试将您的 Excel 文件导出为 CSV 文件,然后以这种方式导入:
import pandas as pd
df1 = pd.read_csv('sample_data.csv')
在这种情况下,你可以得到这个DataFrame,其中列Duration是一个字符串(我添加了一个列id作为参考)。
duration id
0 01:20:34 1
1 12:22:30 2
2 25:01:02 3
3 155:20:56 4
然后为了您的目的,我建议您不要尝试将这些值转换为 datetime
类型,而是 timedelta
。一种策略是用冒号拆分字符串,然后使用这三个字段构建 timedelta 实例:小时、分钟和秒。
import datetime as dt
def converter1(x):
vals = x.split(':')
vals = [int(val) for val in vals ]
out = dt.timedelta(hours=vals[0], minutes=vals[1], seconds=vals[2])
return out
df1['deltat'] = df1['duration'].apply(converter1)
duration id deltat
0 01:20:34 1 0 days 01:20:34
1 12:22:30 2 0 days 12:22:30
2 25:01:02 3 1 days 01:01:02
3 155:20:56 4 6 days 11:20:56
如果您需要将这些值转换为小数小时数或其他新字段,请使用 timedelta
:
中的 total_seconds()
方法
df1['deltat_hr'] = df1['deltat'].apply(lambda x: x.total_seconds()/3600)
duration id deltat deltat_hr
0 01:20:34 1 0 days 01:20:34 1.342778
1 12:22:30 2 0 days 12:22:30 12.375000
2 25:01:02 3 1 days 01:01:02 25.017222
3 155:20:56 4 6 days 11:20:56 155.348889
我需要将 .xlsx sheet 导入到 pandas 中,其中有一列用于关联 activity 的处理时间。此列中的所有条目看起来都像这样:
01:20:34
12:22:30
25:01:02
155:20:56
这表示需要多少小时、分钟和秒。当我使用 pd.read_excel
时,pandas 正确解释了每个小于 24 小时的时间戳,并在前两种情况下按上述方式读取它们。另一方面,超过 24 小时(最后两个)的时间戳被转换为日期时间对象,它又看起来像这样:1900-01-02T14:58:03
而不是 62:58:03
。
有没有简单的解决方法?
我认为部分问题不在Python/Pandas,而在Excel。日期“1900-01-01”是 Excel 使用的基准日期,用数字“1”表示。您可以检查是否在单元格中写入“0”,然后将该单元格格式化为日期,您会得到“1900-01-00”,而“1”会得到“1900-01-01”。
因此,在导入到 pandas 之前尝试将您的 Excel 文件导出为 CSV 文件,然后以这种方式导入:
import pandas as pd
df1 = pd.read_csv('sample_data.csv')
在这种情况下,你可以得到这个DataFrame,其中列Duration是一个字符串(我添加了一个列id作为参考)。
duration id
0 01:20:34 1
1 12:22:30 2
2 25:01:02 3
3 155:20:56 4
然后为了您的目的,我建议您不要尝试将这些值转换为 datetime
类型,而是 timedelta
。一种策略是用冒号拆分字符串,然后使用这三个字段构建 timedelta 实例:小时、分钟和秒。
import datetime as dt
def converter1(x):
vals = x.split(':')
vals = [int(val) for val in vals ]
out = dt.timedelta(hours=vals[0], minutes=vals[1], seconds=vals[2])
return out
df1['deltat'] = df1['duration'].apply(converter1)
duration id deltat
0 01:20:34 1 0 days 01:20:34
1 12:22:30 2 0 days 12:22:30
2 25:01:02 3 1 days 01:01:02
3 155:20:56 4 6 days 11:20:56
如果您需要将这些值转换为小数小时数或其他新字段,请使用 timedelta
:
total_seconds()
方法
df1['deltat_hr'] = df1['deltat'].apply(lambda x: x.total_seconds()/3600)
duration id deltat deltat_hr
0 01:20:34 1 0 days 01:20:34 1.342778
1 12:22:30 2 0 days 12:22:30 12.375000
2 25:01:02 3 1 days 01:01:02 25.017222
3 155:20:56 4 6 days 11:20:56 155.348889