在Pandas中如何对可空日期列使用np.where?
问题:np.where处理日期列时的类型兼容问题
np.where是Pandas中实用的向量化工具,可根据条件修改列值。它处理NumPy原生类型表现良好,但处理日期类型时会触发类型提升错误。
可正常运行的数值类型示例
>>> df1 = pd.DataFrame([["a", 1], ["b", np.nan]], columns=["name", "num"]) >>> df1 name num 0 a 1.0 1 b NaN >>> np.where(df1["num"] < 2, df1["num"], np.nan) array([ 1., nan])
触发错误的日期类型示例
>>> df2 = pd.DataFrame([["a", datetime.datetime(2024,1,2)], ["b", np.nan]], columns=["name", "date"]) >>> df2 name date 0 a 2024-01-02 1 b NaT >>> np.where(df2["date"] < datetime.datetime(2024,3,1), df2["date"], np.nan) Traceback (most recent call last): File "<python-input-10>", line 1, in <module> np.where(df2["date"] < datetime.datetime(2024,3,1), df2["date"], np.nan) ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ numpy.exceptions.DTypePromotionError: The DType <class 'numpy.dtypes.DateTime64DType'> could not be promoted by <class 'numpy.dtypes._PyFloatDType'>. This means that no common DType exists for the given inputs. For example they cannot be stored in a single array unless the dtype is `object`. The full list of DTypes is: (<class 'numpy.dtypes.DateTime64DType'>, <class 'numpy.dtypes._PyFloatDType'>)
请问执行上述日期列相关操作的正确向量化方法是什么?
解决方案
方法1:用pd.NaT替代np.nan
日期类型的缺失值对应pd.NaT(Not a Time),而非数值类型的np.nan。将替换值改为pd.NaT即可解决类型冲突:
>>> np.where(df2["date"] < datetime.datetime(2024,3,1), df2["date"], pd.NaT) array(['2024-01-02T00:00:00.000000', 'NaT'], dtype='datetime64[ns]')
方法2:使用Pandas原生的Series.where()
Pandas的where方法专门针对自身数据类型优化,无需手动处理缺失值类型,直接作用于日期列即可:
>>> df2["date"].where(df2["date"] < datetime.datetime(2024,3,1)) 0 2024-01-02 1 NaT Name: date, dtype: datetime64[ns]
如果需要新增列存储结果,直接赋值即可:
df2["filtered_date"] = df2["date"].where(df2["date"] < datetime.datetime(2024,3,1))
方法3:强制转为object类型(不推荐)
虽然可以通过将结果转为object dtype绕过类型检查,但会丢失日期类型的优化特性,降低运算性能,仅作为兜底方案:
>>> np.where(df2["date"] < datetime.datetime(2024,3,1), df2["date"], np.nan).astype(object) array([datetime.datetime(2024, 1, 2, 0, 0), nan], dtype=object)
内容的提问来源于stack exchange,提问作者YGA
相关产品推荐
相关产品推荐

