【问题标题】:Cannot cast array data from dtype('<M8[ns]') to dtype('float64') according to the rule 'safe'无法根据规则“安全”将数组数据从 dtype('<M8[ns]') 转换为 dtype('float64')
【发布时间】:2018-02-05 00:37:38
【问题描述】:

我正在使用 numpy interp 插入数据点,但给出了无法从 dtype 转换数组数据('

代码sn-p:

import pandas as pd
import numpy as np
def interpolate_fwd_price(row, fx):
    res = np.interp(row['SA_M'], fx['TENOR_DT'], fx['RATE'])
    return res

df = pd.DataFrame({'SA_M': ['2018-02-28','2018-03-10']})
df['SA_M'] = pd.to_datetime(df['SA_M'])
data = pd.DataFrame({'TENOR_DT': ['2017-02-09','2017-03-02','2017-04-03','2017-05-02'], 'RATE':[1.0, 1.2, 1.5, 1.8]})
data['TENOR_DT'] = pd.to_datetime(data['TENOR_DT'])
df['PRICE'] = df.apply(interpolate_fwd_price, fx=data, axis=1)

我进行了一些搜索,但无法找出导致错误的原因。感谢您的意见。

进行一些更改,它可以直接插入日期时间差异而不是直接插入日期时间。仍然有兴趣知道为什么它不能直接插入日期时间。

def interpolate_fwd_price(row, fx):
    fx['DT'] = (fx['TENOR_DT'] - row(['SA_M'])).dt.days
    res = np.interp(0, fx['DT'], fx['RATE'])
    return res

【问题讨论】:

  • 当您询问错误时,您应该指出错误发生的位置。有时它有助于查看部分或全部回溯。但我猜你正在尝试做某种数学,也许是插值,它确实适用于日期。 np.datetime64 是处理日期时间的数组 dtype。它使用 64 位,但我认为这是一个整数值,而不是浮点数。
  • 我应该提到错误发生在最后一行:df['PRICE'] = df.apply(interpolate_fwd_price, fx=data, axis=1)

标签: python pandas numpy interpolation


【解决方案1】:
In [92]: data = pd.DataFrame({'TENOR_DT': ['2017-02-09','2017-03-02','2017-04-03','2017-05-02'], 'RATE':[1.0, 1.2, 1.5, 1.8]})
In [93]: data        # object dtype with strings
Out[93]: 
   RATE    TENOR_DT
0   1.0  2017-02-09
1   1.2  2017-03-02
2   1.5  2017-04-03
3   1.8  2017-05-02
In [94]: data['TENOR_DT'] = pd.to_datetime(data['TENOR_DT'])
In [95]: data
Out[95]: 
   RATE   TENOR_DT
0   1.0 2017-02-09
1   1.2 2017-03-02
2   1.5 2017-04-03
3   1.8 2017-05-02
In [96]: data['TENOR_DT']
Out[96]: 
0   2017-02-09
1   2017-03-02
2   2017-04-03
3   2017-05-02
Name: TENOR_DT, dtype: datetime64[ns]

日期的数组版本:

In [98]: dt = data['TENOR_DT'].values
In [99]: dt
Out[99]: 
array(['2017-02-09T00:00:00.000000000', '2017-03-02T00:00:00.000000000',
       '2017-04-03T00:00:00.000000000', '2017-05-02T00:00:00.000000000'],
      dtype='datetime64[ns]')

可以使用默认的unsafe将其转换为浮点数:

In [100]: dt.astype(float)
Out[100]: array([1.4865984e+18, 1.4884128e+18, 1.4911776e+18, 1.4936832e+18])
In [101]: dt.astype(float, casting='safe')
TypeError: Cannot cast array from dtype('<M8[ns]') to dtype('float64') according to the rule 'safe'

我的猜测是 np.interp 正在使用 safe 转换将这些日期时间值转换为浮点数。

我之前没有尝试过对日期进行interp,所以只能提出一些修复建议。首先,您的日期只是每天不同,所以我们不需要完整的ns 分辨率:

In [107]: dt.astype('datetime64[D]')
Out[107]: 
array(['2017-02-09', '2017-03-02', '2017-04-03', '2017-05-02'],
      dtype='datetime64[D]')

它仍然不允许安全投射,但“不安全”投射会产生看起来合理的数字。您也许可以在插值中使用它们。

In [108]: dt.astype('datetime64[D]').astype(int)
Out[108]: array([17206, 17227, 17259, 17288])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-26
    • 2018-08-15
    • 1970-01-01
    • 2021-01-26
    • 2019-03-11
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多