【问题标题】:Why doesn't astype timedelta64 work on ndarray?为什么 astype timedelta64 不能在 ndarray 上工作?
【发布时间】:2018-02-25 21:33:52
【问题描述】:

为什么.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!

【问题讨论】:

    标签: python pandas numpy casting timedelta


    【解决方案1】:

    请注意,这些是等效的:

    df['FailCast'] = df['FailCast'].values.astype('timedelta64[D]')
    

    df['FailCast'] = np.array([731, 738, 745, 752, 759], dtype='timedelta64[D]')
    

    在获得相同输出后传递.astype(int)

    【讨论】:

    • 看来“FailCast”示例有点进行了转换,但不是一直?我不知道这是否是文本/视图输出层中的一个肤浅的怪癖,或者它有多深......
    【解决方案2】:

    事实上,您所说的“成功”实际上是一种看起来不合时宜的情况。它是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() 与在 pandas Series 上调用 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
    

    【讨论】:

    • 其实我有点迷茫。
    • 是的,它看起来已经做了一些事情。但是为什么astype 调用在“FailCast”情况下产生的结果与我在'Days' 列中调用“Success”的结果不同?
    • 如果我认为“成功”很奇怪,因为它是一个 float64,而不是请求的 timedelta64。我会做更多的研究,看看幕后发生了什么。
    • 好点!我只知道观察到某些事情似乎是错误的;希望你能照亮它!
    猜你喜欢
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 2017-05-02
    相关资源
    最近更新 更多