Python ValueError:时间数据';2006年11月10日24:00';与格式不匹配';%d/%m/%Y%H:%m';

Python ValueError:时间数据';2006年11月10日24:00';与格式不匹配';%d/%m/%Y%H:%m';,python,pandas,datetime,Python,Pandas,Datetime,我试过: df["datetime_obj"] = df["datetime"].apply(lambda dt: datetime.strptime(dt, "%d/%m/%Y %H:%M")) 但我犯了这个错误: ValueError:时间数据“10/11/2006 24:00”的格式不匹配 “%d/%m/%Y%H:%m” 如何正确解决此问题?如文档()所示,小时从00到23。24:00则为错误。此操作不起作用的原因是%H参数仅接受00到23范围内的值(两者均包括在内)。这意味着24:00

我试过:

df["datetime_obj"] = df["datetime"].apply(lambda dt: datetime.strptime(dt, "%d/%m/%Y %H:%M"))
但我犯了这个错误:

ValueError:时间数据“10/11/2006 24:00”的格式不匹配 “%d/%m/%Y%H:%m”


如何正确解决此问题?

如文档()所示,小时从00到23。24:00则为错误。

此操作不起作用的原因是
%H
参数仅接受
00
23
范围内的值(两者均包括在内)。这意味着
24:00
就像错误所说的那样,不是有效的时间字符串

因此,我认为除了将字符串转换为有效格式之外,我们没有太多其他选择。我们可以先将
24:00
替换为
00:00
,然后为这些时间戳增加日期

比如:


因此,最后一行在包含
24:00
的行中添加一天,这样
'10/11/2006 24:00'
将转换为
'11/11/2006 24:00'
。然而,请注意,上述操作相当不安全,因为根据时间戳的格式,这将/不会起作用。因为只有一个冒号,所以上面的代码可能会起作用。但是,例如,如果
datetime
s也有秒,则过滤器可能会在
00:24:00
时触发,因此可能需要一些额外的工作才能使其工作。

您的数据不遵循Python/Pandas
datetime
对象使用的约定。存储特定日期时间的方法只有一种,即
'10/11/2006 24:00'
应重写为
'11/11/2006 00:00'

这里有一种解决问题的方法:

# find datetimes which have '24:00' and rewrite
twenty_fours = df['strings'].str[-5:] == '24:00'
df.loc[twenty_fours, 'strings'] = df['strings'].str[:-5] + '00:00'

# construct datetime series
df['datetime'] = pd.to_datetime(df['strings'], format='%d/%m/%Y %H:%M')

# add one day where applicable
df.loc[twenty_fours, 'datetime'] += pd.DateOffset(1)
以下是一些需要测试的数据:

dateList = ['10/11/2006 24:00', '11/11/2006 00:00', '12/11/2006 15:00']
df = pd.DataFrame({'strings': dateList})
上述转换后的结果:

print(df['datetime'])

0   2006-11-11 00:00:00
1   2006-11-11 00:00:00
2   2006-11-12 15:00:00
Name: datetime, dtype: datetime64[ns]

24:00
不是有效的小时。
%H
的范围是
0您首先是如何获得这些值的?@WillemVanOnsem:这些值出现在输入数据中,我应该对其进行预处理。有没有办法克服这个问题?那么
10/11/2006 24:00
意味着什么呢?现在是
11/11/2006 00:00
?因为这会让事情变得更棘手。好的,谢谢。但我如何解决这个问题呢?是否有可能揭露这些案例并用0代替24?这是一种典型的坏数据形式。你有两个选择。您可以通过修复生成数据的内容(最佳选项)来修复它们,或者通过更改(例如,
'24:'
)通过
'00:'
(Python中的简单操作)来修复数据。很酷,但我也收到了此警告。你知道这是什么意思吗/opt/conda/lib/python3.6/site packages/ipykernel_launcher.py:4:SettingWithCopyWarning:试图在数据帧的切片副本上设置一个值请参见文档中的警告:@ScalaBoy:是的,关于警告有什么不清楚的地方?@ScalaBoy:通过乘法而不是过滤。但不幸的是,这可能会导致额外的效率低下,因为您似乎已经在使用
.apply(…)
性能可能已经不是那么高了:)很好的解释。我觉得您不必替换
'24:00'
,也不必将
str.contains('24:00')
作为单独的步骤进行检查。可以使用布尔级数并重用它。我试图在我的回答中做到这一点。@WillemVanOnsem,明白了,我想这比什么都更符合风格。
print(df['datetime'])

0   2006-11-11 00:00:00
1   2006-11-11 00:00:00
2   2006-11-12 15:00:00
Name: datetime, dtype: datetime64[ns]