让熊猫像楠一样繁殖

2022-07-06 10:05:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在NaT面前获取包含datetime64数据的两个Pandas系列对象的min和max。np.最小值以及np.最大值如果数据类型是float64,就按我想要的方式工作。也就是说,一旦比较中的任何元素为NaN,则NaN将是该比较的结果。例如:

>>> s1
0    0.0
1    1.8
2    3.6
3    5.4
dtype: float64
>>> s2
0    10.0
1    17.0
2     NaN
3    14.0
dtype: float64
>>> np.maximum(s1, s2)
0    10.0
1    17.0
2     NaN
3    14.0
dtype: float64
>>> np.minimum(s1, s2)
0    0.0
1    1.8
2    NaN
3    5.4
dtype: float64

如果s1和s2是datetime64对象,则此操作不起作用:

^{pr2}$

无论计算最小值还是最大值,我都希望索引0、2和3都显示为NaT(我知道numpy的函数可能不是最佳选择,但我没有成功地找到合适的Pandas类似物)

读了一点之后,我发现NaT只是近似的NaN,后者有一个适当的浮点表示。进一步的阅读表明,没有简单的方法让NaT“污染”这些比较。让NaT在最小/最大比较中传播的正确方法是什么?NaN在浮点上下文中的传播方式是什么?也许有熊猫等同于numpy.{maximum,minimum}哪些是NaT感知的?在


Tags: 对象方法numpypandasnpnannat浮点dtypes2float64minimums1maximumdatetime64
3条回答
网友
1楼 ·

^{}似乎是一个不放弃矢量化的解决方案:

s1 = pd.Series([pd.datetime(2099, 12, 31)]*4)
s2 = pd.Series([pd.NaT, pd.datetime(2018, 10, 30), pd.NaT, pd.NaT])

null_check = s1.isnull() | s2.isnull()
res_max = np.maximum(s1, s2).mask(null_check, np.nan)
res_min = np.minimum(s1, s2).mask(null_check, np.nan)

print(res_max)
print(res_min)

0          NaT
1   2099-12-31
2          NaT
3          NaT
dtype: datetime64[ns]
0          NaT
1   2018-10-30
2          NaT
3          NaT
dtype: datetime64[ns]

正如您所发现的,您所看到的行为的原因是pd.NaT有一个关联的int值,该值用于比较操作:

^{pr2}$
网友
2楼 ·

不确定这是最好的方法,但是如果您使用astype将s1和s2的类型更改为object,那么使用np.minimum和{}仍然可以得到一系列的{},例如:

print (np.maximum(s1.astype(object), s2.astype(object)))
0          NaT
1   2199-12-31
2          NaT
3          NaT
Name: 1, dtype: datetime64[ns]
网友
3楼 ·

我想我已经弄清楚了。(好吧,至少我找到了一种方法来剥猫的皮。)虽然不是很漂亮,但比我最初的解决方案在apply()中嵌入所有逻辑要快得多。简单地说,解决方案包括将datetime元素转换为int,映射国家警察局到np.nan公司,正在应用np.最小值/np.maximum,然后转换回datetime64。apply()仍然涉及到,但是逻辑比我原来的逻辑大为减少。(毫无疑问,它还可以改进。我不是一个喜欢熊猫/裸体的人……)

>>> s1 = pd.Series([pd.NaT, pd.datetime(2018, 10, 30), pd.NaT, pd.NaT])
>>> s1
0          NaT
1   2018-10-30
2          NaT
3          NaT
dtype: datetime64[ns]
>>> nanish = int(pd.NaT)
>>> nanish
-9223372036854775808
>>> s2 = pd.to_numeric(s1)
>>> s2
0   -9223372036854775808
1    1540857600000000000
2   -9223372036854775808
3   -9223372036854775808
dtype: int64
>>> s3 = s2.apply(lambda x: np.nan if x == nanish else x)
>>> s3
0             NaN
1    1.540858e+18
2             NaN
3             NaN
dtype: float64
>>> s5 = np.maximum(s3, s4)
>>> s5
0             NaN
1    1.540858e+18
2             NaN
3             NaN
dtype: float64
>>> s6 = pd.to_datetime(s5)
>>> s6
0          NaT
1   2018-10-30
2          NaT
3          NaT
dtype: datetime64[ns]