使用掩码转换DataFrame字符串为日期时部分条目变为NaT的问题
问题
现有如下结构的DataFrame:
Index Hour type Horizon Day BZ Value 0 1 ND D-2 17-12-2022 FI 7258 1 1 ND D-1 16-12-2022 FI 3702 2 1 ND D-1 15-12-2022 FI 3702 3 1 ND D-1 14-12-2022 FI 3702 4 1 ND D-1 13-12-2022 FI 3702 5 1 ND D-1 10-12-2022 FI 3702 6 1 Selected 7 FI 4885
尝试用以下代码筛选type为'ND'的行,将Day列的字符串转为日期类型存入Day2列:
mask = df_long['type'] == 'ND' df_long['Day2']= pd.to_datetime(df_long['Day'][mask],format='%d-%m-%Y')
但结果中不符合掩码条件的行(如type为Selected的行)的Day2值变为了NaT:
Index Hour type Horizon Day BZ Value Day2 0 1 ND D-2 17-12-2022 FI 7258 2022-12-17 00:00:00 1 1 ND D-1 16-12-2022 FI 3702 2022-12-16 00:00:00 2 1 ND D-1 15-12-2022 FI 3702 2022-12-15 00:00:00 3 1 ND D-1 14-12-2022 FI 3702 2022-12-14 00:00:00 4 1 ND D-1 13-12-2022 FI 3702 2022-12-13 00:00:00 5 1 ND D-1 10-12-2022 FI 3702 2022-12-10 00:00:00 6 1 Selected 7 FI 4885 NaT
希望不符合条件的行的Day2值保留Day列的原始内容,该如何解决?
解决方案
方法1:用loc精准赋值
先将Day2列初始化为Day列的原始值,再仅对符合条件的行更新为转换后的日期:
# 初始化Day2为Day的原始值 df_long['Day2'] = df_long['Day'] # 筛选type为ND的行,转换日期并赋值给Day2 mask = df_long['type'] == 'ND' df_long.loc[mask, 'Day2'] = pd.to_datetime(df_long.loc[mask, 'Day'], format='%d-%m-%Y')
这种方式逻辑直观,确保非目标行的Day2值完全保留原始数据。
方法2:用where条件替换
利用pandas的where方法,仅在掩码为True时使用转换后的日期,否则保留原数据:
mask = df_long['type'] == 'ND' df_long['Day2'] = pd.to_datetime(df_long['Day'], format='%d-%m-%Y').where(mask, df_long['Day'])
where函数会根据掩码判断:满足条件时用转换后的日期,不满足时用Day列的原始值。
方法3:用apply逐行处理
通过自定义函数逐行判断并处理,适合复杂条件场景:
def process_day(row): if row['type'] == 'ND': return pd.to_datetime(row['Day'], format='%d-%m-%Y') return row['Day'] df_long['Day2'] = df_long.apply(process_day, axis=1)
注意:此方法在数据量较大时性能不如前两种,优先推荐前两种向量式操作。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

