如何定义函数识别可转为datetime的object类型列?代码结果不符预期求助
问题诊断
你的函数目前只返回['1','3'],核心原因是你用了errors='raise'参数——只要目标列里有任何一个值转换datetime失败,就会触发ValueError,导致该列被跳过。而你的测试数据里,列4、5、6都存在无效日期(比如2015-02-31(2月没有31号)、2015-04-31(4月最多30号)这类不符合日历规则的日期),所以这些列都被原函数排除了,但你希望把它们也算进去,毕竟这些列的大部分值都是符合datetime格式的。
改进后的解决方案
我们可以调整逻辑:不要求列中所有值都能转换成功,而是判断该列是否具备datetime列的特征(即使存在部分无效值)。具体做的时候,我们可以用errors='coerce'来尝试转换(无效值会被转为NaT,但列的类型会变成datetime64),然后通过类型判断和有效值存在性来筛选目标列,同时注意不要修改原始DataFrame。
下面是修改后的代码:
import pandas as pd def find_potential_datetime_cols(DF): # 筛选所有object类型的列,这种写法比原代码更简洁健壮 object_cols = DF.select_dtypes(include=['object']).columns.tolist() potential_dt_cols = [] for col in object_cols: # 临时转换列,无效值转成NaT,不改动原数据 temp_series = pd.to_datetime(DF[col], infer_datetime_format=True, errors='coerce') # 两个判断条件: # 1. 转换后的列确实是datetime类型 # 2. 列中至少有一个有效的datetime值(避免把完全无法转换的列比如'0'算进来) if pd.api.types.is_datetime64_any_dtype(temp_series) and temp_series.notna().any(): potential_dt_cols.append(col) return potential_dt_cols # 测试你的数据 df = pd.DataFrame({ '0': ['a', 'b', 'c','d','e'], '1': ['2015-12-27','2015-12-28', '2015-12-29','2015 12-31 10:00','2016/01/01 15:00'], '2': [11,12,13,14,15], '3': ['2015-12-31','2015-12-29', '2015-12-30','2016-01 11 23:59','2016/02/01 22:00'], '4': ['2015-02-31','2015-02-29', '2015-02-30','2016-03 11 23:59','2016/04/01 22:00'], '5': ['2015-04-31','2015-04-29', '2015-04-30','2016-05 11 23:59','2016/06/01 22:00'], '6': ['2015-04-31','2015-04-29', '2015-04-30','2016-05 11 23:59','2016/06/01 22:00'] }) print(find_potential_datetime_cols(df)) # 输出:['1', '3', '4', '5', '6']
关键改动说明
- 替换了object列的筛选方式:用
select_dtypes比直接索引dtypes.values更简洁,也不容易出错 - 用
errors='coerce'替代errors='raise':这样转换失败的值会变成NaT,不会抛出异常,同时转换后的列会被识别为datetime类型 - 增加了双重判断:
pd.api.types.is_datetime64_any_dtype确保转换后的列确实是datetime类型,避免把完全无法转换的字符串列误判temp_series.notna().any()确保列中至少有一个有效日期,排除像列'0'这种完全和datetime无关的列
- 不修改原DataFrame:创建临时的
temp_series来测试,不会污染你的原始数据
内容的提问来源于stack exchange,提问作者Sanjeev Kallepalli
相关产品推荐
相关产品推荐

