numpy isin问题的时间戳?

Chr*_*per 3 python numpy pandas

我对np.isin函数有一个奇怪的问题.如果我创建一个简短的pd.DatetimeIndex,以及该索引中存在的日期:

test_index = pd.date_range(start='2000-01-01', end='2000-01-15',freq='B')
test_date = test_index[0]
Run Code Online (Sandbox Code Playgroud)

我可以检查test_date实际上是索引的第一个元素:

test_date == test_index[0]
True
Run Code Online (Sandbox Code Playgroud)

但是np.isin函数似乎无法识别test_index中的test_date:

np.isin(test_index, test_date)
array([False, False, False, False, False, False, False, False, False,
       False])
Run Code Online (Sandbox Code Playgroud)

如果我这样写,就会发生这种情况

np.isin(test_index.values, test_date)
Run Code Online (Sandbox Code Playgroud)

这似乎是错误和奇怪的.test_date和test_index [0]的数据类型以pd.Timestamp的形式给出,它们之间没有明显的区别.任何帮助感激不尽.

alk*_*asm 6

这不是一个尴尬的问题,这是一个熊猫问题.问题是因为pd.date_range创建一个DatetimeIndex特殊类型的索引,并以与访问它们时不同的方式存储对象.来自以下文档DatetimeIndex:

datetime64数据的不可变ndarray,内部表示为int64,可以装入作为datetime子类的Timestamp对象,并携带频率信息等元数据.

这很难解析." type1数据数组,表示为type2,type3在索引时为您提供对象."

我实际上并没有从熊猫那里获得相同的类型; Pandas 的类型test_datepandas._libs.tslib.Timestamp0.22.0,与本文档一致.

>>> test_index.dtype 
dtype('<M8[ns]')

>>> type(test_date)
pandas._libs.tslib.Timestamp
Run Code Online (Sandbox Code Playgroud)

正如文档所述,这Timestamp有额外的元数据,在numpy中转换不好:

>>> np.array(test_date)
array(Timestamp('2000-01-03 00:00:00', freq='B'), dtype=object)
Run Code Online (Sandbox Code Playgroud)

你可以看到我刚刚得到一个对象......那个对象绝对不是存储在对象中的对象DatetimeIndex.这是numpy中隐含的实际情况.从文档上np.isin()(在Notes部分):

如果test_elements是一个集合(或其他非序列集合),它将被转换为具有一个元素的对象数组.

正如我们所看到的,值被推入这个object数组,而不是datetime64数组,所以你不会在test_index数组中找到你的对象.

最好的办法是使用a上的内置方法DatetimeIndex来搜索它,但你也可以明确地投射,因此numpy知道发生了什么.以下是一些不同的方法:

>>> np.isin(test_index, np.datetime64(test_date))
array([ True, False, False, False, False, False, False, False, False,
   False])
>>> test_index == test_date
array([ True, False, False, False, False, False, False, False, False,
   False])
>>> test_index.isin([test_date])
array([ True, False, False, False, False, False, False, False, False,
   False])
>>> test_index.contains(test_date) # if you just need yes or no
True
Run Code Online (Sandbox Code Playgroud)