Lás*_*zló 36 python datetime datetimeoffset pandas
我很困惑pandas如何用这些行吹出日期时间对象的界限:
import pandas as pd
BOMoffset = pd.tseries.offsets.MonthBegin()
# here some code sets the all_treatments dataframe and the newrowix, micolix, mocolix counters
all_treatments.iloc[newrowix,micolix] = BOMoffset.rollforward(all_treatments.iloc[i,micolix] + pd.tseries.offsets.DateOffset(months = x))
all_treatments.iloc[newrowix,mocolix] = BOMoffset.rollforward(all_treatments.iloc[newrowix,micolix]+ pd.tseries.offsets.DateOffset(months = 1))
Run Code Online (Sandbox Code Playgroud)
这all_treatments.iloc[i,micolix]
是一个日期时间设置pd.to_datetime(all_treatments['INDATUMA'], errors='coerce',format='%Y%m%d')
,并且INDATUMA
是格式中的日期信息20070125
.
这个逻辑似乎适用于模拟数据(没有错误,日期有意义),所以目前我无法在我的整个数据失败时重现,并出现以下错误:
pandas.tslib.OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 2262-05-01 00:00:00
Run Code Online (Sandbox Code Playgroud)
jet*_*com 51
由于pandas表示以纳秒分辨率表示的时间戳,因此使用64位整数表示的时间跨度限制为大约584年
pd.Timestamp.min
Out[54]: Timestamp('1677-09-22 00:12:43.145225')
In [55]: pd.Timestamp.max
Out[55]: Timestamp('2262-04-11 23:47:16.854775807')
Run Code Online (Sandbox Code Playgroud)
而且你的价值超出了这个范围2262-05-01 00:00:00,因此outofbounds错误
直接出来:http://pandas-docs.github.io/pandas-docs-travis/timeseries.html#timestamp-limitations
Paw*_*erg 21
将errors
参数设置为pd.to_datetime
to 'coerce'
会导致越界值的替换NaT
.引用文档:
如果是"强制",那么无效解析将被设置为NaT
例如:
datetime_variable = pd.to_datetime(datetime_variable, errors = 'coerce')
Run Code Online (Sandbox Code Playgroud)
这显然不会修复数据,但仍允许处理非NaT数据点.
sha*_*359 20
您看到此错误消息 “OutOfBoundsDatetime:超出范围纳秒时间戳:3000-12-23 00:00:00”的原因是因为 pandas 时间戳数据类型以纳秒分辨率存储日期(来自文档)。
这意味着日期值必须在范围内
pd.Timestamp.min(1677-09-21 00:12:43.145225) and
pd.Timestamp.max(2262-04-11 23:47:16.854775807)
Run Code Online (Sandbox Code Playgroud)
即使您只想要精度为秒或微秒的日期,pandas 仍然会以纳秒为单位在内部存储它。pandas 中没有选项可以存储上述范围之外的时间戳。
这是令人惊讶的,因为像 sql server 这样的数据库和像 numpy 这样的库允许存储超出这个范围的日期。大多数情况下最多使用 64 位来存储日期。
但区别就在这里。 SQL Server以纳秒分辨率存储日期,但精度最高为 100 ns(相对于 pandas 中的 1 ns)。由于空间有限(64 位),因此这是范围与精度的问题。使用 pandas 时间戳,我们可以获得更高的精度,但日期范围更小。
对于 numpy(pandas 构建在 numpy 之上)datetime64 数据类型,
但是,如果您选择以纳秒为单位存储并且日期超出范围,那么 numpy 将自动环绕该日期,您可能会得到意外的结果(在下面的第四个解决方案中引用)。
np.datetime64("3000-06-19T08:17:14.073456178", dtype="datetime64[ns]")
> numpy.datetime64('1831-05-11T09:08:06.654352946')
Run Code Online (Sandbox Code Playgroud)
现在有了 pandas,我们有以下选项,
import pandas as pd
data = {'Name': ['John', 'Sam'], 'dob': ['3000-06-19T08:17:14', '2000-06-19T21:17:14']}
my_df = pd.DataFrame(data)
Run Code Online (Sandbox Code Playgroud)
1)如果您同意丢失超出范围的数据,则只需使用以下参数将超出范围的日期转换为 NaT(不是时间)。
my_df['dob'] = pd.to_datetime(my_df['dob'], errors = 'coerce')
Run Code Online (Sandbox Code Playgroud)
2)如果你不想丢失数据,那么你可以将值转换为python日期时间类型。这里,“dob”列的类型为 pandas 对象,但单个值的类型为 python datetime。然而这样做我们将失去矢量化函数的好处。
import datetime as dt
my_df['dob'] = my_df['dob'].apply(lambda x: dt.datetime.strptime(x,'%Y-%m-%dT%H:%M:%S') if type(x)==str else pd.NaT)
print(type(my_df.iloc[0][1]))
> <class 'datetime.datetime'>
Run Code Online (Sandbox Code Playgroud)
3)另一种选择是如果可能的话使用numpy而不是pandas系列。对于 pandas 数据框,您可以将系列(或 df 中的列)转换为 numpy 数组。单独处理数据,然后将其连接回数据框。
4)我们还可以按照文档中的建议使用 pandas 时间跨度。在使用此数据类型之前,请检查黑白时间戳和周期的差异。这里的日期范围和频率与 numpy 类似(上面在 numpy 部分中提到)。
my_df['dob'] = my_df['dob'].apply(lambda x: pd.Period(x, freq='ms'))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
40830 次 |
最近记录: |