2013-07-05 55 views
2

我想將pandas DateTimeIndex轉換爲excel日期(自12/30/1899以來的天數)..我嘗試在需要datetime64s並返回excel日期的函數上使用numpy.vectorize。我對numpy向量化的表現感到驚訝 - 在第一次調用時,測試調用來查看返回類型,vectorize按照提供的方式在datetime64中傳遞。在後續的調用中,它會傳入datetime64的內部存儲類型 - 在我的情況下是很長的。在內部,_get_ufunc_and_otypes電話:在datetime64和vectorize之間,在numpy 1.7.1中是否存在不良交互?

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)/ 1天。但是,這種行爲似乎很奇怪(當功能被矢量類型改變)

這裏是我的示例代碼:

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) 

回答

1

日期時間和timedeltas需要使用的基礎數據(你只是做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 
+0

這一工程 - 非常感謝。我寫它的方式的行爲對我來說仍然很奇怪(特別是第一次調用通過了datetime64,隨後的調用獲得了底層的np.int64) – DaveBlob

相關問題