如何使用Polars处理分隔文件中的不一致列(不规则行)?
如何使用Polars处理分隔文件中的不一致列(不规则行)?
我太懂你这种头疼的情况了——处理这种行与行列数参差不齐的CSV文件,Polars的默认行为还偏偏跟第二行的结构挂钩,确实让人摸不着头脑。咱们直接说解决方案,帮你搞定这个问题:
先搞清楚问题根源
你遇到的现象本质是Polars的schema推断逻辑:当你设置skip_rows=1且infer_schema_length=None时,它会从**第二行(也就是你实际读取的第一行数据)**来推断列数和类型。如果这一行的列数比后面的少,后续行多出来的列就会触发报错;反之如果这一行列数最多,后面的行就会自动补null。
解决方案1:动态适配最大列数(推荐,保留所有数据)
这个方法能让Polars自动适配文件里的最大列数,不管哪一行列数最多都能完整读取,少的列自动补null。步骤如下:
- 先读取文件的所有行,算出最大列数
- 扩展原表头(或者生成新列名)到最大列数的长度
- 用扩展后的列名列表读取文件
针对ADLS上的文件,代码可以这么写:
# 先读取所有行(按换行符拆分,相当于把每行当成一个字段) lines = pl.read_csv( 'abfss://container@account.dfs.core.windows.net/sample.csv', has_header=False, sep='\n' ).to_series().to_list() # 提取表头和数据行 header = lines[0].strip().split(',') data_lines = lines[1:] # 计算数据行中的最大列数 max_cols = max(len(line.strip().split(',')) for line in data_lines) # 扩展表头:原表头不够的部分用col_3、col_4这类命名补充 new_columns = header + [f'col_{i}' for i in range(len(header), max_cols)] # 正式读取文件,用扩展后的列名 df = pl.read_csv( 'abfss://container@account.dfs.core.windows.net/sample.csv', has_header=True, new_columns=new_columns, infer_schema=False, ignore_errors=True )
这样处理后,你示例里的失败数据就能正常读取,多出来的列会以col_3、col_4的形式保留,少数据的行自动补null。
解决方案2:截断多余列(业务允许时用)
如果你的业务场景可以接受截断那些超过初始schema的列,那直接用报错提示里的参数就行:
pl.read_csv( 'sample.csv', has_header=False, skip_rows=1, infer_schema=False, ignore_errors=True, truncate_ragged_lines=True )
这个参数会自动把超过推断列数的部分砍掉,不会触发报错,但会丢失多余列的数据,所以得根据业务需求来选。
小提示:优化参数设置
你之前的代码里设置了has_header=False+skip_rows=1,其实如果文件第一行是表头的话,直接设置has_header=True更准确,也能避免手动跳过行的麻烦,配合上面的动态列名方法效果更好。
备注:内容来源于stack exchange,提问作者Neeraj Vernekar
相关产品推荐
相关产品推荐

