Me topé con este extraño comportamiento al intentar verificar si un DataFrame
tiene valores por encima de cierta fecha, mientras que ese DataFrame también puede contener pd.NaT
Las comparaciones de valores se comportan como se espera:
import pandas as pd pd.NaT > pd.to_datetime('2018-10-15') # False
Las comparaciones con una Series
también se comportan como se espera:
s = pd.Series([pd.NaT, pd.to_datetime('2018-10-16')]) s > pd.to_datetime('2018-10-15') #0 False #1 True #dtype: bool
Pero la comparación de DataFrame
no es correcta:
s.to_frame() > pd.to_datetime('2018-10-15') # 0 #0 True #1 True
Me parece que el problema es que la comparación inicialmente devuelve NaN
que es (¿en algún momento?) Obligado a True
dado el comportamiento de:
df = pd.DataFrame([[pd.NaT, pd.to_datetime('2018-10-16')], [pd.to_datetime('2018-10-16'), pd.NaT]]) df >= pd.to_datetime('2018-10-15') # 0 1 #0 True True #1 True True df.ge(pd.to_datetime('2018-10-15')) # 0 1 #0 NaN 1.0 #1 1.0 NaN
Entonces, ¿realmente no podemos usar los operadores > = <=
al comparar un DataFrame
y necesitamos confiar en .lt .gt .le .ge
seguido de un .fillna(0)
?
df.ge(pd.to_datetime('2018-10-15')).fillna(0) # 0 1 #0 0.0 1.0 #1 1.0 0.0
Este fue un error que se solucionará en la próxima versión de pandas (0.24.0):
In [1]: import pandas as pd; pd.__version__ Out[1]: '0.24.0.dev0+1504.g9642fea9c' In [2]: s = pd.Series([pd.NaT, pd.to_datetime('2018-10-16')]) In [3]: s > pd.to_datetime('2018-10-15') Out[3]: 0 False 1 True dtype: bool In [4]: s.to_frame() > pd.to_datetime('2018-10-15') Out[4]: 0 0 False 1 True In [5]: df = pd.DataFrame([[pd.NaT, pd.to_datetime('2018-10-16')], ...: [pd.to_datetime('2018-10-16'), pd.NaT]]) ...: In [6]: df >= pd.to_datetime('2018-10-15') Out[6]: 0 1 0 False True 1 True False In [7]: df.ge(pd.to_datetime('2018-10-15')) Out[7]: 0 1 0 False True 1 True False
Para el problema de GitHub correspondiente, consulte: https://github.com/pandas-dev/pandas/issues/22242