TypeError报错:split()不支持'expand'参数,DataFrame时间列处理遇阻
问题描述
我有一个包含开始时间和结束时间列的DataFrame,由于这些列可能存在无效值,我添加了try-except块。我尝试统一时间格式并最终将其保存为pandas datetime.time类型,代码如下:
for i in range(df.shape[0]): try: df.loc[i,'start time'] = pd.to_datetime(df.loc[i,'start time'].split(':', expand=True) .apply(lambda col: col.str.zfill(2)) .fillna('00') .agg(':'.join, axis=1)).dt.time except: pass try: df.loc[i,'end time'] = pd.to_datetime(df.loc[i,'end time'].str.split(':', expand=True) .apply(lambda col: col.str.zfill(2)) .fillna('00') .agg(':'.join, axis=1)).dt.time except: pass
运行代码时出现错误:TypeError: 'expand' is an invalid keyword argument for split(),请问忽略了什么问题?
问题分析与解决
错误根源
你混淆了两种split方法的用法:df.loc[i,'start time']取到的是单个标量值(比如某一行的时间字符串或NaN),此时调用的是Python原生的str.split()方法——而expand是pandas Series专属的str.split()方法才有的参数,原生字符串的split根本不支持这个参数,所以报错。
两种修复方案
方案1:用pandas向量化操作(推荐,效率更高)
直接对整列做批量处理,这是pandas的核心优势:
def clean_time_col(col): # 把时间字符串拆分成多列 split_cols = col.str.split(':', expand=True) # 每列都补成两位数字格式 split_cols = split_cols.apply(lambda c: c.str.zfill(2)) # 缺失的部分用00填充 split_cols = split_cols.fillna('00') # 重新拼接成标准时间字符串 cleaned_time_str = split_cols.agg(':'.join, axis=1) # 转换为datetime.time类型,无效值自动设为NaT return pd.to_datetime(cleaned_time_str, errors='coerce').dt.time # 批量处理两列 df['start time'] = clean_time_col(df['start time']) df['end time'] = clean_time_col(df['end time'])
方案2:保留逐行循环(不推荐,效率较低)
如果一定要逐行处理,就得用原生字符串的split,手动完成补零和拼接:
for i in range(df.shape[0]): # 处理start time try: time_val = df.loc[i, 'start time'] if pd.notna(time_val): # 转成字符串后拆分 parts = str(time_val).split(':') # 每个部分补成两位,最多取时分秒三个部分 parts = [p.zfill(2) for p in parts[:3]] # 不足三个部分的补00(比如只有小时的话,补分钟和秒) while len(parts) < 3: parts.append('00') # 拼接后转成time类型 df.loc[i, 'start time'] = pd.to_datetime(':'.join(parts)).time() except (ValueError, TypeError): pass # 处理end time try: time_val = df.loc[i, 'end time'] if pd.notna(time_val): parts = str(time_val).split(':') parts = [p.zfill(2) for p in parts[:3]] while len(parts) < 3: parts.append('00') df.loc[i, 'end time'] = pd.to_datetime(':'.join(parts)).time() except (ValueError, TypeError): pass
额外提醒
- 尽量避免逐行循环DataFrame,数据量大时性能会差很多,向量化操作才是pandas的正确用法。
- 不要用空的
except,指定具体的异常类型(比如上面的ValueError和TypeError),避免掩盖其他未知错误。
内容的提问来源于stack exchange,提问作者Soumya Pandey
相关产品推荐
相关产品推荐

