TypeError: Iterator operand 0 dtype could not be cast from dtype('<M8[us]') to dtype('<M8[D]') according to the rule 'safe'
先描述下博主遇到这个问题的情况,然后描述针对该情况的解决办法.
问题描述:
博主遇到这个问题是在 使用ricequant平台中封装的jupyter notebook中做单因子有效性分析使用 alphalens模块的时候,具体报错情况如下图:
当时也是网上搜索各种办法,大概定位问题 是时间的类型转换出了问题,但还是没有解决,过了几天,把这个问题咨询了大斌哥, 大斌哥说他之前也遇到过, 当时花了2天最终通过定位源码, 才解决的, 感谢大斌哥 !!! 下面我把大斌哥的方法搬过来,供大家参考.
首先bug报错最后定位在 上图 第920行上面显示的
diff_custom_calendar_timedeltas(start, end, freq)
这个函数上, 追踪其来源 alphalens/utils.py. 大斌哥是源码出了问题. 先查看了ricequant平台封装的alphalens版本,
具体方法见上图 In [19 ] 块的代码,或如下:
import alphalens alphalens.__version__
我的显示是 0.3.2 版本. 他让我去github上找版本0.3.0 或 0.3.3试试, 查看下载链接 [https://github.com/quantopian/alphalens/releases](https://github.com/quantopian/alphalens/releases) , 我下载了版本0.3.3 然后上传到 ricequant 封装的jupyter notebook中.具体方法如下图:
然后就是不用 ricequant提供的alphalens,而是从我们上传的这个 alphalens33 中导包.
from alphalens33 import performance from alphalens33 import plotting from alphalens33 import tears from alphalens33 import utils
然后, 再运行代码,就不会再报错.
问题虽然解决了,但根本原因还是没有说清楚,下面说说alphalens 版本0.3.2和 0.3.3 这两个版本中对于 diff_custom_calendar_timedeltas(start, end, freq) 函数的具体实现区别.
首先看下代码对比图:
对比发现. 0.3.3版本对 start ,end 这两个日期参数都使用astype进行了强制类型转换,
所以解决代码bug的办法,其实就 把这两个要传入的日期参数进行强制类型转换成 [ 'datetime64[D]' ] ! ! ! ! ! !
定位到自己的代码,start,end这两个日期参数来自与 utils.get_clean_factor_and_forward_returns()函数中对于 pirce参数值 price_all, 该值是pd.DataFrame 数据结构,
打印 price_all.index,显示如下:
DatetimeIndex(['2019-01-02', '2019-01-03', '2019-01-04', '2019-01-07' ], dtype='datetime64[ns]', freq=None)
单独取值 price_all.index[0] ,显示结果如下:
price_all.index[0] # 输出: Timestamp('2019-01-02 00:00:00')
可以看到是时间戳 Timestamp 类型,这就是问题根源, 于是博主尝试修改 price_all.index,想让其 price_all.index[0] 结果是 'datetime64[D]' 类型,
比如使用 重新构建索引的方法,代码如下, 但单独取值 price_all.index[0] 还是 Timestamp 类型.
### 此代码无效,此代码无效,此代码无效 !!! date_li = np.array(price_all.index.values).astype('datetime64[D]') price_all.set_index(pd.DatetimeIndex(date_li),inplace=True)
故最后还是尝试失败了,希望有高手知道怎么处理的帮忙,提供下思路或方法,谢谢 ! ! !