这是一个有趣的问题。我做了一些调查并尽力解释了其中一些内容,尽管仍有一件事情我不明白,那就是当我们执行
b<a时为什么会出现
pandas
抛出错误而不是
numpy
。
关于你的问题:
如果a可以与b进行比较,我认为我们应该能够反过来比较?
这并不一定正确。这取决于比较运算符的实现方式。
以这个测试类为例:
class TestCom(int):
def __init__(self, a):
self.value = a
def __gt__(self, other):
print('TestComp __gt__ called')
return True
def __eq__(self, other):
return self.a == other
在这里,我定义了我的__gt__
(<
)方法,无论其他值如何,它始终返回true。而__eq__
(==
)保持不变。
现在看看以下比较:
a = TestCom(9)
print(a)
a > 100
a > '100'
'100' < a
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-486-8aee1b1d2500> in <module>()
1
----> 2 '100' > a
TypeError: '>' not supported between instances of 'str' and 'TestCom'
回到你的情况。从timestamps_sourceCode可以看出,我唯一能想到的就是pandas.Timestamp
进行了某些类型检查和转换。
当我们比较a和b(pd.Timestamp
与np.datetime64
),Timestamp.__richcmp__
函数进行比较,如果它是np.datetime64
类型,则将其转换为pd.Timestamp
类型并进行比较。
# we can do the following to have a comparison of say b > a
# this converts a to np.datetime64 - .asm8 is equivalent to .to_datetime64()
b > a.asm8
# or we can confert b to datetime64[ms]
b.astype('datetime64[ms]') > a
# or convert to timestamp
pd.to_datetime(b) > a
我觉得令人惊讶的是,我原以为问题在于纳秒而不是时间戳,但即使你执行以下操作,np.datetime64与pd.Timestamp之间的比较也会失败。
a = pd.Timestamp('2013-03-24 05:32:00.00000001')
a.nanosecond
b < a
从源代码来看,似乎我们可以使用==
和!=
运算符。但是即使它们也不能按预期工作。请看下面的示例:
a = pd.Timestamp('2013-03-24 05:32:00.00000000')
b = np.datetime64('2013-03-24 05:32:00.00000000', 'ns')
b == a
a == b
我认为这是149-152行或163-166行的结果。如果您使用“==”,则返回
False
,如果使用
!=
,则返回
True
,而不实际比较值。
编辑:
nanosecond
功能是在版本
0.23.0
中添加的。因此,您可以执行以下操作:
pd.Timestamp('2013-03-23T05:33:00.000000022',unit ='ns')
。因此,当您比较
np.datetime64
时,它将转换为具有
ns
精度的
pd.Timestamp
。
请注意,
pd.Timestamp
应该替代Python的datetime:
Timestamp是pandas中等价于Python的Datetime,并且在大多数情况下可以互换。
但是Python的datetime不支持纳秒-这里有一个很好的答案解释为什么SO_Datetime。 pd.Timestamp
支持比较两者,即使您的Timestamp
中有纳秒。当您将一个datetime
对象与带有ns
的pd.Timestamp
对象进行比较时,它们具有 _compare_outside_nanorange 来执行比较。
回到np.datetime64
,需要注意的一点是,正如在这篇文章SO中很好地解释的那样,它是对int64
类型的包装器。因此,如果我执行以下操作,这并不奇怪:
1 > a
a > 1
两者都会报错,错误信息为无法将类型“Timestamp”与类型“int”进行比较
。
因此,在执行b > a
时,比较必须在int
级别上进行,这个比较将由np.greater()
函数 np.greater 来完成 - 也可以查看ufunc_docs。
注意:我无法确认这一点,因为numpy文档过于复杂。如果有任何numpy专家能够发表评论,那将是有帮助的。
如果是这种情况,如果
np.datetime64
的比较基于
int
,那么上面使用
a == b
和
b == a
的示例就有意义了。因为当我们执行
b == a
时,我们将
b
的
int
值与
pd.Timestamp
进行比较,这将始终返回
Flase
(对于
==
)和
True
(对于
!=
)。这与执行
123 == '123'
相同,此操作不会失败,只会返回
False
。