如何用PyArrow解析非标准日期格式CSV并写入Parquet文件?
解决PyArrow解析非标准CSV日期格式的问题
你的问题出在PyArrow默认的时间戳解析器无法处理0或空白值,同时需要对%Y%m00和%Y0000这类格式做特殊转换。下面提供两种可行的解决方案,按需选择:
方案一:加载CSV时自定义日期转换器(推荐)
直接在读取CSV阶段处理所有格式转换,一次完成:
- 定义日期解析函数,覆盖四种格式场景:
import pyarrow as pa import pyarrow.csv as csv import datetime def parse_custom_date(s): s = s.strip() # 处理未知日期(0或空白) if s in ('0', ''): return None # 仅指定年份的格式:转为当年第一天 if s.endswith('0000'): s = f"{s[:4]}0101" # 仅指定年月的格式:转为当月第一天 elif s.endswith('00'): s = f"{s[:6]}01" # 标准年月日格式直接解析 return datetime.datetime.strptime(s, "%Y%m%d").date()
- 配置
ConvertOptions,指定目标列的类型和转换器:
convert_options = csv.ConvertOptions( # 替换为你的实际日期列名 column_types={"date_column": pa.date32()}, convert_fields=[ ("date_column", lambda s: parse_custom_date(s)) ] ) # 读取CSV并转换 table = csv.read_csv("your_input.csv", convert_options=convert_options) # 写入Parquet pa.parquet.write_table(table, "output.parquet")
方案二:先读取为字符串列,加载后批量处理
如果需要更灵活的批量转换逻辑,可先将日期列读取为字符串,再用PyArrow Compute API处理:
import pyarrow as pa import pyarrow.csv as csv import pyarrow.compute as pc # 先读取日期列为字符串类型 convert_options = csv.ConvertOptions( column_types={"date_column": pa.string()} ) table = csv.read_csv("your_input.csv", convert_options=convert_options) # 1. 处理空白和0为null值 date_str = pc.coalesce(pc.strip(table["date_column"]), pa.scalar("")) is_null = pc.or_(pc.equal(date_str, "0"), pc.equal(date_str, "")) # 2. 转换非标准格式:%Y0000→%Y0101,%Y%m00→%Y%m01 date_str = pc.replace_substring(date_str, "0000", "0101", occurrence=-1) date_str = pc.replace_substring(date_str, "00", "01", occurrence=-1) # 3. 解析为date类型,保留null值 date_col = pc.strptime(date_str, format="%Y%m%d", unit="s").cast(pa.date32()) date_col = pc.if_else(is_null, pa.scalar(None, type=pa.date32()), date_col) # 替换原表中的日期列 table = table.set_column( table.schema.get_field_index("date_column"), "date_column", date_col ) # 写入Parquet pa.parquet.write_table(table, "output.parquet")
注意事项
- 两处代码中的
date_column需替换为你CSV中实际的日期列名称 - 若存在多个日期列,需对每个列重复对应处理逻辑
- 方案二使用PyArrow原生Compute API,大数据量下性能更优
内容的提问来源于stack exchange,提问作者sligocki
相关产品推荐
相关产品推荐

