python - 具有混合时间和日期时间的列的 Pandas 问题

标签 python excel pandas datetime time

我有一列来自 Excel,应该包含持续时间(以小时为单位) - 示例:02:00:00 -
如果所有这些持续时间都小于 24:00,则效果很好,但如果其中一个持续时间超过该时间,则它在 pandas 中显示为 1900-01-03 08:00:00 (因此日期时间) 因此数据类型为 dtype('O')。

df = pd.DataFrame({'duration':[datetime.time(2, 0), datetime.time(2, 0),
       datetime.datetime(1900, 1, 3, 8, 0),
       datetime.datetime(1900, 1, 3, 8, 0),
       datetime.datetime(1900, 1, 3, 8, 0),
       datetime.datetime(1900, 1, 3, 8, 0),
       datetime.datetime(1900, 1, 3, 8, 0),
       datetime.datetime(1900, 1, 3, 8, 0), datetime.time(1, 0),
       datetime.time(1, 0)]})

# Output
    duration
0   02:00:00
1   02:00:00
2   1900-01-03 08:00:00
3   1900-01-03 08:00:00
4   1900-01-03 08:00:00
5   1900-01-03 08:00:00
6   1900-01-03 08:00:00
7   1900-01-03 08:00:00
8   01:00:00
9   01:00:00

但是,如果我尝试转换为时间或日期时间,我总是会收到错误。

TypeError: <class 'datetime.time'> is not convertible to datetime

今天如果我不解决这个问题,所有大于 24:00 的持续时间都会消失。

最佳答案

您的问题出在读取 Excel 文件的引擎上。它将具有特定格式的单元格(例如 [h]:mm:sshh:mm:ss)转换为 datetime.datetimedatetime.time 对象。然后这些数据会被传输到 pandas DataFrame 中,所以这实际上不是 pandas 问题。

在开始破解 Excel 阅读器引擎之前,在 Excel 中解决问题可能会更容易。这是一个小示例文件;

enter image description here

您可以下载hereduration 由 Excel 自动设置格式,duration_text 是在输入值之前将列格式设置为“文本”时得到的结果, duration_to_text 是在 Excel 自动设置值(第一列)格式后将格式更改为文本时得到的结果。

现在,使用 pandas 导入后您就拥有了所需的一切:

df = pd.read_excel('path_to_file')

df
              duration duration_text  duration_to_text
0             12:30:00      12:30:00          0.520833
1  1900-01-01 00:30:00      24:30:00          1.020833

# now you can parse to timedelta:
pd.to_timedelta(df['duration_text'], errors='coerce')
0   0 days 12:30:00
1   1 days 00:30:00
Name: duration_text, dtype: timedelta64[ns]

# or
pd.to_timedelta(df['duration_to_text'], unit='d', errors='coerce') 
0   0 days 12:29:59.999971200                     # note the precision issue ;-)
1   1 days 00:29:59.999971200
Name: duration_to_text, dtype: timedelta64[ns]

另一个可行的选择是将 Excel 文件另存为 csv 并将其导入到 pandas DataFrame。上面使用的示例 xlsx 看起来像 this例如。


如果除了在 pandas 中重新处理之外别无选择,则可以选择专门处理 datetime.time 对象和 datetime.datetime 对象,例如

import datetime

# where you have datetime (incorrect from excel)
m = [isinstance(i, datetime.datetime) for i in df.duration]

# convert to timedelta where it's possible
df['timedelta'] = pd.to_timedelta(df['duration'].astype(str), errors='coerce')

# where you have datetime, some special treatment is needed...
df.loc[m, 'timedelta'] = df.loc[m, 'duration'].apply(lambda t: pd.Timestamp(str(t)) - pd.Timestamp('1899-12-31'))

df['timedelta'] 
0   0 days 12:30:00
1   1 days 00:30:00
Name: timedelta, dtype: timedelta64[ns]

关于python - 具有混合时间和日期时间的列的 Pandas 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70858332/

相关文章:

python - Jenkins Python 打印控制台输出

python - 如何在pygame中更改光标?

python - groupby 上的“值的长度与索引的长度不匹配”

python - pandas xlsxwriter,格式表标题 - 不是工作表标题

python - 有没有办法识别一个单词是否有相同的字母相邻?

vba - For 循环案例选择错误

excel - VBA删除事件工作表

Python XLWT - 自定义格式问题

Python pandas 仅提取所需的列和列中的所需值

python - 如何使从 netCDF (.nc) 加载的数组可写?