我想将pandas DateTimeIndex转换为excel日期(自18/30/1899以来的天数)..我试图在一个采用datetime64s的函数上使用numpy.vectorize并返回一个excel日期。我对numpy vectorize的行为表示惊讶 - 在第一次调用时,看到返回类型的测试调用,vectorize在datetime64中传递。在后续调用中,它传递datetime64的内部存储类型 - 在我的情况下为long。在内部,_get_ufunc_and_otypes调用:
inputs = [asarray(_a).flat[0] for _a in args]
outputs = func(*inputs)
虽然_vectorize_call执行以下操作:
inputs = [array(_a, copy=False, subok=True, dtype=object)
for _a in args]
outputs = ufunc(*inputs)
事实证明,我可以轻松地使用内部numpy数组算法(x - day0)/ 1day。但是这种行为似乎很奇怪(当函数被矢量化时类型改变)
这是我的示例代码:
import numpy
DATETIME64_ONE_DAY = numpy.timedelta64(1,'D')
DATETIME64_DATE_ZERO = numpy.datetime64('1899-12-30T00:00:00.000000000')
def excelDateToDatetime64(x):
return DATETIME64_DATE_ZERO + numpy.timedelta64(int(x),'D')
def datetime64ToExcelDate(x):
print type(x)
return (x - DATETIME64_DATE_ZERO) / DATETIME64_ONE_DAY
excelDateToDatetime64_Array = numpy.vectorize(excelDateToDatetime64)
datetime64ToExcelDate_Array = numpy.vectorize(datetime64ToExcelDate)
excelDates = numpy.array([ 41407.0, 41408.0, 41409.0, 41410.0, 41411.0, 41414.0 ])
datetimes = excelDateToDatetime64_Array(excelDates)
excelDates2 = datetime64ToExcelDate(datetimes)
print excelDates2 # Works fine
# TypeError: ufunc subtract cannot use operands with types dtype('int64') and dtype('<M8[ns]')
# You can see from the print that the type coming in is inconsistent
excelDates2 = datetime64ToExcelDate_Array(datetimes)
答案 0 :(得分:1)
日期时间和时间点需要使用基础数据处理(您只需要arr.view('i8')
获取,这些是np.int64
)
根据基础值定义常量
In [94]: DATETIME_DATE_ZERO_VIEW = DATETIME64_DATE_ZERO.view('i8')
In [95]: DATETIME_DATE_ZERO_VIEW
Out[95]: -2209161600000000000
In [96]: DATETIME64_ONE_DAY_VALUE = DATETIME64_ONE_DAY.astype('m8[ns]').item()
In [97]: DATETIME64_ONE_DAY_VALUE
Out[97]: 86400000000000L
In [106]: def vect(x):
.....: return (x-DATETIME_DATE_ZERO_VIEW)/DATETIME64_ONE_DAY_VALUE
.....:
In [107]: f = np.vectorize(vect)
传递基础np.int64的视图
In [109]: f(datetimes.view('i8'))
Out[109]: array([41407, 41408, 41409, 41410, 41411, 41414])
熊猫方式
In [98]: Series(datetimes).apply(lambda x: (x.value-DATETIME_DATE_ZERO_VIEW)/DATETIME64_ONE_DAY_VALUE)
Out[98]:
0 41407
1 41408
2 41409
3 41410
4 41411
5 41414
dtype: int64