gpt4 book ai didi

python - numpy 和 pandas timedelta 错误

转载 作者:太空狗 更新时间:2023-10-29 22:25:58 24 4
gpt4 key购买 nike

在 Python 中,我有一个使用 pandas 生成(或从 CSV 文件中读取)的日期数组,我想为每个日期添加一年。我可以使用 pandas 但不能使用 numpy 来让它工作。我究竟做错了什么?还是 pandas 或 numpy 中的错误?

谢谢!

import numpy as np
import pandas as pd
from pandas.tseries.offsets import DateOffset

# Generate range of dates using pandas.
dates = pd.date_range('1980-01-01', '2015-01-01')

# Add one year using pandas.
dates2 = dates + DateOffset(years=1)

# Convert result to numpy. THIS WORKS!
dates2_np = dates2.values

# Convert original dates to numpy array.
dates_np = dates.values

# Add one year using numpy. THIS FAILS!
dates3 = dates_np + np.timedelta64(1, 'Y')

# TypeError: Cannot get a common metadata divisor for NumPy datetime metadata [ns] and [Y] because they have incompatible nonlinear base time units

最佳答案

np.timedelta64(1, 'Y') 添加到 dtype datetime64[ns] 的数组中不起作用,因为年份不对应固定数字纳秒。有时一年是 365 天,有时是 366 天,有时甚至还有一个额外的闰秒。 (注意额外的闰秒,例如发生在 2015-06-30 23:59:60 的闰秒,不能表示为 NumPy datetime64s。)

据我所知,向 NumPy datetime64[ns] 数组添加年份的最简单方法是将其分解为组成部分,例如年、月和日,对整数数组进行计算,然后重组 datetime64 数组:

def year(dates):
"Return an array of the years given an array of datetime64s"
return dates.astype('M8[Y]').astype('i8') + 1970

def month(dates):
"Return an array of the months given an array of datetime64s"
return dates.astype('M8[M]').astype('i8') % 12 + 1

def day(dates):
"Return an array of the days of the month given an array of datetime64s"
return (dates - dates.astype('M8[M]')) / np.timedelta64(1, 'D') + 1

def combine64(years, months=1, days=1, weeks=None, hours=None, minutes=None,
seconds=None, milliseconds=None, microseconds=None, nanoseconds=None):
years = np.asarray(years) - 1970
months = np.asarray(months) - 1
days = np.asarray(days) - 1
types = ('<M8[Y]', '<m8[M]', '<m8[D]', '<m8[W]', '<m8[h]',
'<m8[m]', '<m8[s]', '<m8[ms]', '<m8[us]', '<m8[ns]')
vals = (years, months, days, weeks, hours, minutes, seconds,
milliseconds, microseconds, nanoseconds)
return sum(np.asarray(v, dtype=t) for t, v in zip(types, vals)
if v is not None)

# break the datetime64 array into constituent parts
years, months, days = [f(dates_np) for f in (year, month, day)]
# recompose the datetime64 array after adding 1 to the years
dates3 = combine64(years+1, months, days)

产量

In [185]: dates3
Out[185]:
array(['1981-01-01', '1981-01-02', '1981-01-03', ..., '2015-12-30',
'2015-12-31', '2016-01-01'], dtype='datetime64[D]')

尽管看起来代码太多,但实际上比添加 1 年的 DateOffset 更快:

In [206]: %timeit dates + DateOffset(years=1)
1 loops, best of 3: 285 ms per loop

In [207]: %%timeit
.....: years, months, days = [f(dates_np) for f in (year, month, day)]
.....: combine64(years+1, months, days)
.....:
100 loops, best of 3: 2.65 ms per loop

当然,pd.tseries.offsets提供了一整套偏移量,在使用 NumPy datetime64s 时没有简单的对应物。

关于python - numpy 和 pandas timedelta 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31407463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com