Pandas判断日期是否为月初及非月初日期日月交换实现
错误原因
你遇到的报错和结果异常,核心问题是Python原生三元表达式不支持对Pandas Series做逐元素判断:
- 第一种写法里
d['dates1'].dt.is_month_start == True返回的是一整列布尔值,Python无法把整列布尔值转换成单个判断条件,因此抛出ValueError: The truth value of a Series is ambiguous错误。 - 第二种写法用
is True判断,本质是对比对象内存地址,布尔Series和True不可能是同一个对象,所以判断结果永远为False,输出结果自然不符合预期。
正确实现方案
推荐用向量化函数np.where做逐行条件判断,性能远高于逐行apply,两种实现方式可以按需选择:
方案1:直接调整字符串格式输出
import pandas as pd import numpy as np dummy_data1 = { 'id': ['1', '2', '3', '4', '5'], 'Feature1': ['A', 'C', 'E', 'G', 'I'], 'Feature2': ['B', 'D', 'F', 'H', 'J'], 'dates': ['01/09/2020','10/01/2020','01/11/2020','01/12/2020','01/02/2021']} df1 = pd.DataFrame(dummy_data1, columns = ['id', 'Feature1', 'Feature2', 'dates']) # 转换为datetime类型判断是否为月初 df1['dates_dt'] = pd.to_datetime(df1['dates'], format="%d/%m/%Y", errors="coerce") # 条件判断:月初保留原日期,否则交换日月 df1['adjusted_dates'] = np.where( df1['dates_dt'].dt.is_month_start, df1['dates'], df1['dates'].str.split('/', expand=True).apply(lambda x: f"{x[1]}/{x[0]}/{x[2]}", axis=1) )
方案2:输出调整后的datetime类型(方便后续日期计算)
df1['adjusted_dt'] = np.where( df1['dates_dt'].dt.is_month_start, df1['dates_dt'], # 非月初的日期直接按 月/日/年 格式解析,等价于交换日月 pd.to_datetime(df1['dates'], format="%m/%d/%Y", errors="coerce") ) # 如需转回%d/%m/%Y格式的字符串,可执行下面的代码 df1['adjusted_dates'] = df1['adjusted_dt'].dt.strftime("%d/%m/%Y")
运行结果说明
你的测试数据中只有10/01/2020解析后为2020年1月10日,不是月初,因此会被调整为01/10/2020,其余日期均为当月第一天,保留原格式,完全符合需求。
内容的提问来源于stack exchange,提问作者Srinivas
相关产品推荐
相关产品推荐

