调用Oura API获取combined_df时出现时间格式不匹配错误求助
Python调用Oura Ring数据时日期格式不匹配问题排查
问题现象
使用OuraClientDataFrame调用Oura Ring数据时,readiness_df(start='2018-11-01')能正常返回数据,无日期相关问题;但调用combined_df_edited(start='2018-11-01')触发时间格式不匹配错误,报错信息如下:
Traceback (most recent call last): File "c:\Users\stefa\OneDrive\Coding\Oura\test.py", line 22, in <module> combined_df = client.combined_df_edited(start=start) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\client_pandas.py", line 198, in combined_df_edited sleep_df = self.sleep_df(start, end, metrics) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\client_pandas.py", line 104, in sleep_df return SleepConverter(convert_cols).convert_metrics(df) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py", line 119, in convert_metrics df = super().convert_metrics(df) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py", line 86, in convert_metrics df = self._convert_to_dt(df, dt_metrics) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py", line 57, in _convert_to_dt df[dt_metric] = pd.to_datetime(df[dt_metric], format="%Y-%m-%d %H:%M:%S") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\tools\datetimes.py", line 1050, in to_datetime values = convert_listlike(arg._values, format) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\tools\datetimes.py", line 453, in _convert_listlike_datetimes return _array_strptime_with_fallback(arg, name, utc, format, exact, errors) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\tools\datetimes.py", line 484, in _array_strptime_with_fallback result, timezones = array_strptime(arg, fmt, exact=exact, errors=errors, utc=utc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "pandas\_libs\tslibs\strptime.pyx", line 530, in pandas._libs.tslibs.strptime.array_strptime File "pandas\_libs\tslibs\strptime.pyx", line 351, in pandas._libs.tslibs.strptime.array_strptime ValueError: time data "2018-11-15T08:02:30+01:00" doesn't match format "%Y-%m-%d %H:%M:%S", at position 0. You might want to try: - passing `format` if your strings have a consistent format; - passing `format='ISO8601'` if your strings are all ISO8601 but not necessarily in exactly the same format; - passing `format='mixed'`, and the format will be inferred for each element individually. You might want to use `dayfirst` alongside this.
用户使用的代码如下:
import pandas as pd from datetime import date, timedelta from oura import OuraClientDataFrame from api_token import API_TOKEN oura_token = API_TOKEN # Your Oura token client = OuraClientDataFrame(personal_access_token=oura_token) # Make connection # Check you the connection is working and you have access to your account who_am_i_df = client.user_info_df() print(who_am_i_df) start = '2018-11-01' days = 7 week_past = str(date.today() - timedelta(days)) ####### # Pull readiness data and combined features into separate dataframes # Start is set to beginning of 01-NOV-2018 -> earliest available months for me readiness_df = client.readiness_df(start=start) print(readiness_df.head()) combined_df = client.combined_df_edited(start=start)
注:这段代码在Spyder环境中可正常运行,仅当前环境报错。
问题根源
问题出在oura库的converters.py文件中,第57行硬编码了时间转换格式为"%Y-%m-%d %H:%M:%S",但Oura API返回的时间是带时区的ISO8601格式(如2018-11-15T08:02:30+01:00),两者格式不匹配导致报错。
Spyder能正常运行的原因是:Spyder环境中的pandas版本较低,旧版本pd.to_datetime会自动兼容格式;而当前环境使用的新版本pandas对格式校验更严格,必须完全匹配指定格式才会执行转换。
解决办法
1. 修改库源码(临时快速解决)
找到本地Python环境中oura库的converters.py文件,路径为C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py,定位到第57行:
df[dt_metric] = pd.to_datetime(df[dt_metric], format="%Y-%m-%d %H:%M:%S")
将其修改为以下两种方式之一:
- 指定ISO8601格式:
df[dt_metric] = pd.to_datetime(df[dt_metric], format="ISO8601") - 去掉format参数,让pandas自动推断格式:
df[dt_metric] = pd.to_datetime(df[dt_metric])
2. 自定义数据转换(更稳妥,不修改库文件)
绕过库自带的转换逻辑,手动处理时间列:
# 获取未转换的原始睡眠数据 sleep_raw = client.sleep_df(start=start, convert=False) # 手动转换所有时间列(根据实际列名调整,比如bedtime_start、bedtime_end等) time_columns = ['bedtime_start', 'bedtime_end'] for col in time_columns: sleep_raw[col] = pd.to_datetime(sleep_raw[col]) # 同理处理其他数据类型 activity_raw = client.activity_df(start=start, convert=False) for col in ['day_start', 'day_end']: activity_raw[col] = pd.to_datetime(activity_raw[col]) readiness_raw = client.readiness_df(start=start, convert=False) for col in ['day_start', 'day_end']: readiness_raw[col] = pd.to_datetime(readiness_raw[col]) # 合并数据(参考库中combined_df_edited的逻辑) combined_df = pd.merge(sleep_raw, activity_raw, on='summary_date', how='outer') combined_df = pd.merge(combined_df, readiness_raw, on='summary_date', how='outer')
3. 降级pandas版本
如果不想修改代码或库文件,可降级到旧版pandas,让它自动兼容格式:
pip install pandas==1.5.3
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

