numpy isin问题的时间戳?

时间:2018-09-29 03:00:01

标签: python pandas numpy

我在使用np.isin函数时遇到了一个奇怪的问题。如果我创建一个简短的pd.DatetimeIndex以及该索引中存在的日期:

test_date == test_index[0]
True

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

np.isin(test_index, test_date)
array([False, False, False, False, False, False, False, False, False,
       False])

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

np.isin(test_index.values, test_date)

如果我将其写为

,则会发生这种情况
private class UserViewHolder extends RecyclerView.ViewHolder {
    public TextView title;
    public CheckBox commonCheckbox, itemCheckbox;
    public UserViewHolder(View view) {
        super(view);
        itemCheckbox=view.findViewById(R.id.itemcheckbox);
        title=view.findViewById(R.id.title);
        commonCheckbox = view.findViewById(R.id.commoncheckbox);
    }
}

这似乎是错误和奇怪的。 test_date和test_index [0]的数据类型都指定为pd.Timestamp,它们之间没有明显的区别。非常感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

这不是一个小问题,而是一个熊猫问题。问题是因为pd.date_range创建了DatetimeIndex,这是一种特殊的索引,并且存储的对象与访问对象时得到的对象不同。来自the docs on DatetimeIndex

  

datetime64数据的不变ndarray,内部表示为int64,可以装箱到Timestamp对象中,这些对象是datetime的子类,并携带元数据(例如频率信息)。

这很难解析。 “由type1表示的type2数据数组,在索引时为您提供type3个对象。”

我实际上并没有从熊猫那里得到每种相同的类型。对于Pandas 0.22.0,test_date的类型为pandas._libs.tslib.Timestamp,与本文档一致。

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

>>> type(test_date)
pandas._libs.tslib.Timestamp

如文档所述,此Timestamp具有其他元数据,在numpy中无法很好地转换:

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

您可以看到我刚得到一个对象...该对象绝对不是DatetimeIndex中存储的对象。这实际上是在numpy中隐式发生的。在docs on np.isin()中(在“注释”部分中):

  

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

因此,正如我们所看到的,该值正被推入此object数组而不是datetime64数组,因此您不会在test_index数组中找到对象。

最好的选择是使用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