You need to enable JavaScript to run this app. Spark Python如何从日志CSV数据生成指定结构的DataFrame
优惠活动
大模型
产品
解决方案
定价
更多

Spark Python如何从日志CSV数据生成指定结构的DataFrame

Spark Python CSV结构化提取实现方案

需求说明

读取日志文件存储路径,从日志中提取CSV文本表数据,输出包含CSV原表字段+序列号+时间戳的DataFrame,最终可输出表数据的JSON格式,具体要求如下:

  • 首先从数据库读取serial_no、test_date、s3_path三个字段的元数据
  • s3_path字段存储对应CSV日志文件的S3路径
  • 输出要求为包含CSV表全部字段、主键、时间戳的结构化DataFrame

现有实现进度

已通过如下伪代码从Redshift读取元数据得到初始DataFrame:

df = sparkSession.read \
            .format("com.databricks.spark.redshift") \
            .option("url",
                    "some url with id{}&password={}".format(
                        redshift_user, redshift_pass)) \
            .option("query", query) \
            .option("tempdir", s3_redshift_temp_dir) \
            .option("forward_spark_s3_credentials", True)
df = df_context.load()

初始DataFrame结构示例:

+-------------+-------------------+--------------------+
|serial_number|          test_date|             s3_path|
+-------------+-------------------+--------------------+
|     A0123456|2019-07-10 04:11:52|s3://test-bucket-...|
|     A0123456|2019-07-24 23:48:03|s3://test-bucket-...|
+-------------+-------------------+--------------------+

由于无法将SparkContext传递到worker节点,已通过boto3实现读取S3文件的UDF,注册后调用得到包含CSV字符串字段的中间DataFrame:

spark.udf.register("read_s3_file", read_s3_file)
df_with_string_csv = df.withColumn('table_csv_data', read_s3_file(drive_event_tab.s3_path))

中间DataFrame示例如下,其中table_csv_data字段存储完整的带表头CSV文本:

+-------------+-------------------+--------------------+----------------------+
|serial_number|          test_date|             s3_path|    table_csv_data    |
+-------------+-------------------+--------------------+----------------------+
|     1050D1B0|2019-05-07 15:41:11|s3://test-bucket-...|timestamp,partition,offset,key,value...|
+-------------+-------------------+--------------------+----------------------+

table_csv_data字段内容示例:

timestamp,partition,offset,key,value
1625218801350,97,33009,2CKXTKAT_20210701193302_6400_UCMP,458969040
1625218801349,41,33018,3FGW9S6T_20210701193210_6400_UCMP,17569160

实现方案(得到目标结构化DataFrame)

依赖导入

from pyspark.sql import functions as F
from pyspark.sql.types import StructType, StructField, LongType, StringType

步骤1:定义CSV字段Schema(可选,推荐显式指定避免类型推断错误)

csv_schema = StructType([
    StructField("timestamp", LongType(), nullable=True),
    StructField("partition", LongType(), nullable=True),
    StructField("offset", LongType(), nullable=True),
    StructField("key", StringType(), nullable=True),
    StructField("value", LongType(), nullable=True)
])

步骤2:拆分CSV字符串并行转列、解析字段

Spark 3.0及以上版本(推荐使用from_csv内置函数)

# 按换行符拆分CSV文本为行数组
df_split = df_with_string_csv.withColumn("csv_lines", F.split(F.col("table_csv_data"), "\n"))
# 过滤空行、表头行后炸开为多行
df_explode = df_split.withColumn("csv_line", F.explode(F.expr("filter(csv_lines, x -> x is not null and trim(x) != '' and not x starts with 'timestamp,')")))
# 按Schema解析CSV行
df_parsed = df_explode.withColumn("csv_fields", F.from_csv(F.col("csv_line"), schema=csv_schema, options={"sep": ","}))
# 提取所需字段得到最终DataFrame
final_df = df_parsed.select(
    "serial_number",
    "test_date",
    F.col("csv_fields.*")
)

Spark 2.x版本兼容方案(手动拆分字段)

# 按换行符拆分CSV文本为行数组
df_split = df_with_string_csv.withColumn("csv_lines", F.split(F.col("table_csv_data"), "\n"))
# 过滤空行、表头行后炸开为多行
df_explode = df_split.withColumn("csv_line", F.explode(F.expr("filter(csv_lines, x -> x is not null and trim(x) != '' and not x like 'timestamp,%')")))
# 按逗号拆分每行字段,强转类型后取别名
df_explode = df_explode.withColumn("fields", F.split(F.col("csv_line"), ","))
final_df = df_explode.select(
    "serial_number",
    "test_date",
    F.col("fields")[0].cast(LongType()).alias("timestamp"),
    F.col("fields")[1].cast(LongType()).alias("partition"),
    F.col("fields")[2].cast(LongType()).alias("offset"),
    F.col("fields")[3].alias("key"),
    F.col("fields")[4].cast(LongType()).alias("value")
)

步骤3:输出JSON格式(可选)

final_df.write.json("你的存储路径", mode="overwrite")

最终得到的DataFrame结构与需求完全一致。

内容的提问来源于stack exchange,提问作者LoganPi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 11:39:02