【问题标题】:Getting Out of bounds nanosecond timestamp error while using fillna in python?在 python 中使用 fillna 时出现越界纳秒时间戳错误?
【发布时间】:2021-03-15 03:41:48
【问题描述】:

我在尝试将默认值传递给空值列时收到 out of bounds nanosecond timestamp 错误

df3['check_date']=df3['eventDate0142'].fillna(df3['statusDateTi'].fillna(pd.to_datetime('9999-12-31')))

如何解决这个问题?

【问题讨论】:

    标签: python pandas dataframe datetime timestamp


    【解决方案1】:

    问题在于 pandas maximal Timestamp 是:

    print (pd.Timestamp.max)
    2262-04-11 23:47:16.854775807
    

    所以在 pandas 中会引发错误:

    print (pd.to_datetime('9999-12-31'))
    OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 9999-12-31 00:00:00
    

    示例

    df1 = pd.DataFrame({'eventDate0142': [np.nan,  np.nan, '2016-04-01'], 
                       'statusDateTi': [np.nan, '2019-01-01', '2017-04-01']})
    
    df3 = df1.apply(pd.to_datetime)
    
    print (df3)
      eventDate0142 statusDateTi  
    0           NaT          NaT 
    1           NaT   2019-01-01  
    2    2016-04-01   2017-04-01  
    

    可能的解决方案是使用纯 python,但是所有 pandas datetimelike 方法都失败了 - 所有数据都转换为 dates:

    from datetime import  date
    
    print (date.fromisoformat('9999-12-31'))
    9999-12-31
    
    
    df3['check_date'] = (df3['eventDate0142'].dt.date
                            .fillna(df3['statusDateTi'].dt.date
                            .fillna(date.fromisoformat('9999-12-31'))))
    print (df3)
      eventDate0142 statusDateTi  check_date
    0           NaT          NaT  9999-12-31
    1           NaT   2019-01-01  2019-01-01
    2    2016-04-01   2017-04-01  2016-04-01
    
    print (df3.dtypes)
    eventDate0142    datetime64[ns]
    statusDateTi     datetime64[ns]
    check_date               object
    dtype: object
    

    或者通过Series.dt.to_period将时间戳转换为每日周期,然后将Periods用于representing out of bounds spans

    print (pd.Period('9999-12-31'))
    9999-12-31
    
    df3['check_date'] = (df3['eventDate0142'].dt.to_period('d')
                            .fillna(df3['statusDateTi'].dt.to_period('d')
                            .fillna(pd.Period('9999-12-31'))))
    print (df3)
      eventDate0142 statusDateTi  check_date
    0           NaT          NaT  9999-12-31
    1           NaT   2019-01-01  2019-01-01
    2    2016-04-01   2017-04-01  2016-04-01
    
    print (df3.dtypes)
    eventDate0142    datetime64[ns]
    statusDateTi     datetime64[ns]
    check_date            period[D]
    dtype: object
    

    如果分配回所有列:

    df3['eventDate0142'] = df3['eventDate0142'].dt.to_period('d')
    df3['statusDateTi'] = df3['statusDateTi'].dt.to_period('d')
    df3['check_date'] = (df3['eventDate0142']
                            .fillna(df3['statusDateTi']
                            .fillna(pd.Period('9999-12-31'))))
    print (df3)
      eventDate0142 statusDateTi  check_date
    0           NaT          NaT  9999-12-31
    1           NaT   2019-01-01  2019-01-01
    2    2016-04-01   2017-04-01  2016-04-01
    
    print (df3.dtypes)
    eventDate0142    period[D]
    statusDateTi     period[D]
    check_date       period[D]
    dtype: object
    

    【讨论】:

    • 收到错误Can only use .dt accessor with datetimelike values
    • @LDF_VARUM_ELLAM_SHERIAAVUM - 如果使用9999-12-31,这确实是个问题。解决方案是只在熊猫中使用Periods。或者如果可能,不要替换为9999-12-31
    • 我没找到你
    • @LDF_VARUM_ELLAM_SHERIAAVUM - 好的,在熊猫日期时间9999-12-31不能使用,如果想使用.dt函数,因为最大日期时间是2262-04-11 23:47:16.854775807
    • @LDF_VARUM_ELLAM_SHERIAAVUM - 所以如果使用date.fromisoformat('9999-12-31'),那么列转换为对象则不能使用.dt函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 2021-05-25
    • 2017-02-15
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 2018-09-01
    相关资源
    最近更新 更多