gpt4 book ai didi

python - 在 Python2.7 中比较 Timestamp 和 datetime64 时的奇怪行为

转载 作者:太空宇宙 更新时间:2023-11-03 11:39:46 25 4
gpt4 key购买 nike

有没有人遇到过类似下面的情况,如果我们让a成为Timestamp , b成为datetime64 , 然后比较 a < b很好,但是 b < a返回错误。

如果a可以与 b 进行比较, 我认为我们应该能够以相反的方式进行比较?

例如(Python 2.7):

>>> a
Timestamp('2013-03-24 05:32:00')
>>> b
numpy.datetime64('2013-03-23T05:33:00.000000000')
>>> a < b
False
>>> b < a
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "pandas\_libs\tslib.pyx", line 1080, in pandas._libs.tslib._Timestamp.__richcmp__ (pandas\_libs\tslib.c:20281)
TypeError: Cannot compare type 'Timestamp' with type 'long'

非常感谢!

最佳答案

这是一个有趣的问题。我已经做了一些挖掘并尽力解释其中的一些,尽管我仍然不明白的一件事是为什么我们得到 pandas抛出错误而不是 numpy当我们做 b<a .

关于您的问题:

If a can be compared to b, I thought we should be able to compare the other way around?

这不一定是真的。这仅取决于比较运算符的实现。

以这个测试类为例:

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)
# Output: 9

# my def of __ge__
a > 100

# Ouput: TestComp __gt__ called
# True

a > '100'
# Ouput: TestComp __gt__ called
# True

'100' < a

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-486-8aee1b1d2500> in <module>()
1 # this will not use my def of __ge__
----> 2 '100' > a

TypeError: '>' not supported between instances of 'str' and 'TestCom'

所以回到你的案例。看着 timestamps_sourceCode我唯一能想到的是pandas.Timestamp如果可能,进行一些类型检查和转换。

当我们比较 a 和 b(pd.Timestampnp.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

令我惊讶的是,我认为问题出在 nanoseconds 上不在时间戳中,即使您执行以下操作,np.datetime64 与 pd.Timestamp 之间的比较也会失败。

a = pd.Timestamp('2013-03-24 05:32:00.00000001')
a.nanosecond # returns 10
# doing the comparison again where they're both ns still fails
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 # returns False

a == b # returns True

我认为这是第 149-152 或 163-166 行的结果。他们返回的地方False如果您使用 ==True对于 != ,实际上没有比较这些值。

编辑:nanosecond版本中添加了功能 0.23.0 .所以你可以做类似 pd.Timestamp('2013-03-23T05:33:00.000000022', unit='ns') 的事情.所以是的,当你比较 np.datetime64它将被转换为 pd.Timestampns精度。

请注意 pd.Timestamp应该是 python 的日期时间的替代品:

Timestamp is the pandas equivalent of python's Datetime and is interchangeable with it in most cases.

但是 python 的日期时间不支持纳秒 - 很好的答案在这里解释了为什么 SO_Datetime . pd.Timestamp即使您的 Timestamp 也支持两者之间的比较里面有纳秒。当你比较 datetime反对 pd.Timestamp对象 ns他们有_compare_outside_nanorange这将进行比较。

回到np.datetime64 ,这里要注意的一件事在这篇文章中解释得很好 SO 它是 int64 上的包装器吗?输入。因此,如果我执行以下操作,请不要感到惊讶:

1 > a
a > 1

两者都会出错 Cannot compare type 'Timestamp' with type 'int' .

所以在你做 b > a 的时候比较大部分是在 int 上进行的级别,此比较将由 np.greater() 完成函数 np.greater - 也看看 ufunc_docs .

Note: I'm unable to confirm this, the numpy docs are too complex to go through. If any numpy experts can comment on this, that'll be helpful.

如果是这样的话,如果比较np.datetime64基于int ,然后是上面的例子 a == bb == a说得通。从什么时候开始b == a我们比较 int b 的值反对pd.Timestamp这将始终返回 Flase对于 ==True对于 != .

这和说 123 == '123' 一样, 这个操作不会失败,它只会返回 False .

关于python - 在 Python2.7 中比较 Timestamp 和 datetime64 时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51847671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com