在以下示例中,为什么.astype('timedelta64[D]')无法转换ndarray

df = pd.DataFrame(pd.date_range('2017-01-01', periods=5, freq='W'), columns=['Val'])
df['Base'] = pd.datetime(2015, 1, 1)
df['Days'] = (df['Val'] - df['Base']).astype('timedelta64[D]') # Success
df['FailCast'] = (df['Val'].values - df['Base'].values).astype('timedelta64[D]') # Failure

print (df)

         Val       Base   Days   FailCast
0 2017-01-01 2015-01-01  731.0   731 days
1 2017-01-08 2015-01-01  738.0   738 days
2 2017-01-15 2015-01-01  745.0   745 days
3 2017-01-22 2015-01-01  752.0   752 days
4 2017-01-29 2015-01-01  759.0   759 days


特别要考虑的是,在以下情况下将其作为单独的操作应用时,它将成功转换值:

df['FailCast'] = df['FailCast'].astype('timedelta64[D]') # Success!

最佳答案

实际上,您称“成功”的情况实际上似乎有些失常。它是一个float64而不是请求的timedelta64

为什么?

为什么是float64?由于该方法:

pandas.dtypes.cast.astype_nansafe()


在其中显示以下行:

result = arr.astype(dtype).astype(np.float64)


调用此路径是因为以下行:

(df['Val'] - df['Base']).astype('timedelta64[D]')


调用:NDFrame.astype,其中此行:

(df['Val'].values - df['Base'].values).astype('timedelta64[D]')


调用numpy.ndarray.astype()

差异是由于中间产品的类型不同。

底线:

在numpy数组上调用astype()的行为与在熊猫系列上调用astype()的行为不同。

测试代码:

df = pd.DataFrame(pd.date_range('2017-01-01', periods=5, freq='W'),
                  columns=['Val'])
df['Base'] = pd.datetime(2015, 1, 1, 12)
df['Days'] = (df['Val'] - df['Base']).astype('timedelta64[D]')  # Success
df['FailCast'] = (df['Val'].values - df['Base'].values).astype(
    'timedelta64[D]')  # Failure

print(df)
print(df.dtypes)


结果:

<class 'pandas.core.series.Series'>
<class 'numpy.ndarray'>

         Val       Base   Days FailCast
0 2017-01-01 2015-01-01  731.0 731 days
1 2017-01-08 2015-01-01  738.0 738 days
2 2017-01-15 2015-01-01  745.0 745 days
3 2017-01-22 2015-01-01  752.0 752 days
4 2017-01-29 2015-01-01  759.0 759 days

Val          datetime64[ns]
Base         datetime64[ns]
Days                float64
FailCast    timedelta64[ns]
dtype: object

关于python - 为什么typetype timedelta64在ndarray上不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48978697/

10-11 07:34