如何简化Pandas中对不含指定年份的cleaned_date赋值为None的逻辑?
问题描述
我的DataFrame结构如下:
x date_from cleaned_date 1 21 JUNE 23.59 2024-06-23 2 18TH JUN 23:59 2024-06-18 3 01TH JULY (23.59 HRS) 2024-07-01 4 28th June 2023 2023-06-28 5 5TH MAY 2023 2023-05-05 6 JUNE 27, 2023 2023-06-27
我编写了从date_from列提取正确日期的代码,但该代码会自动补充不存在的年份信息。因此我写了一段代码,将date_from中不含指定年份且非空的行的cleaned_date字段设为None,代码如下:
df.loc[(~df['date_from'].astype('str').str.contains('2025')) & (~df['date_from'].astype('str').str.contains('2024')) & (df['date_from'].astype('str') != 'nan') & (~df['date_from'].astype('str').str.contains('2023')) & (~df['date_from'].astype('str').str.contains('2022')) & (~df['date_from'].astype('str').str.contains('2021')) & (~df['date_from'].astype('str').str.contains('2020')) & (~df['date_from'].astype('str').str.contains('2019')), 'cleaned_date'] = None
但需要检查的年份还有很多,请问是否可以用循环或其他更简洁的方式实现该逻辑?
解决方案
当然可以,用正则表达式或年份列表生成匹配模式,能大幅简化代码,两种实用方法如下:
方法1:正则匹配年份范围
直接用正则匹配指定区间的4位年份,反向筛选不含这些年份且非空的行:
# 匹配2019到2025之间的4位年份,可直接修改数字调整范围 year_pattern = r'20(19|20|21|22|23|24|25)' # 筛选条件:非空 且 不匹配上述年份模式 mask = df['date_from'].notna() & ~df['date_from'].astype(str).str.contains(year_pattern, regex=True) # 对符合条件的行设置cleaned_date为None df.loc[mask, 'cleaned_date'] = None
比如要匹配2010-2025的年份,只需把正则改成r'20(1[0-9]|2[0-5])'即可。
方法2:基于年份列表生成匹配规则
如果年份是离散的,先定义年份列表,再拼接成正则模式,后续调整年份只需修改列表:
# 定义需要检查的年份列表 target_years = ['2019', '2020', '2021', '2022', '2023', '2024', '2025'] # 拼接成正则匹配模式,用|分隔多个年份 year_pattern = '|'.join(target_years) # 筛选条件:非空 且 不包含列表中的任何年份 mask = df['date_from'].notna() & ~df['date_from'].astype(str).str.contains(year_pattern, regex=True) df.loc[mask, 'cleaned_date'] = None
另外注意:df['date_from'].notna()比df['date_from'].astype('str') != 'nan'更准确,前者是专门检测缺失值的方法,不会把真正的字符串'nan'误判为空值。
内容的提问来源于stack exchange,提问作者Tmiskiewicz
相关产品推荐
相关产品推荐

