Pyspark如何处理Excel来源DataFrame的拆分表头及未命名列
Pyspark合并Excel两行表头实现方案
前置依赖
需要先确保Spark环境已经安装了com.crealytics:spark-excel依赖包(版本和你使用的Spark、Scala版本对应即可),该包支持直接读取xlsx格式文件。
具体实现步骤
- 第一步:读取Excel原始内容,不默认把第一行解析为表头
from pyspark.sql import SparkSession import calendar # 初始化SparkSession spark = SparkSession.builder.appName("merge_excel_header").getOrCreate() # 读取Excel文件,关闭自动识别表头 df_raw = spark.read.format("com.crealytics.spark.excel") \ .option("header", "false") \ .option("inferSchema", "false") \ .load("你的文件存储路径/目标文件.xlsx")
- 第二步:提取前两行的表头内容
# 提取第一行表头内容转为列表 row1 = df_raw.first() header1 = [str(col_val).strip() for col_val in row1] # 提取第二行表头内容转为列表 row2 = df_raw.collect()[1] header2 = [str(col_val).strip() for col_val in row2]
- 第三步:按规则拼接生成新列名
如果不需要把英文月份转为两位数字,直接按规则拼接即可:
new_columns = [] for h1, h2 in zip(header1, header2): # 第一行是Unnamed开头时直接取第二行内容作为列名,否则两行内容用下划线拼接 if h1.startswith("Unnamed"): new_columns.append(h2) else: new_columns.append(f"{h1}_{h2}")
如果需要和示例一致把Jul、Aug转为07、08的数字格式,可以增加月份映射逻辑:
# 生成英文月份缩写到两位数字的映射字典 month_map = {name.upper(): f"{num:02d}" for num, name in enumerate(calendar.month_abbr) if num} new_columns = [] for h1, h2 in zip(header1, header2): if h1.startswith("Unnamed"): new_columns.append(h2) else: # 校验是否为月份缩写,是则转换为数字格式 h2_transform = month_map.get(h2.upper(), h2) new_columns.append(f"{h1}_{h2_transform}")
- 第四步:过滤掉前两行表头,给正式数据设置新列名
# 过滤保留第三行及以后的正式数据,同时设置新列名 df_final = df_raw.rdd.zipWithIndex() \ .filter(lambda x: x[1] >= 2) \ .map(lambda x: x[0]) \ .toDF(new_columns) # 验证结果 df_final.show()
补充说明
- 如果需要读取指定sheet,可在读取Excel的参数中添加
.option("dataAddress", "'Sheet名称'!A1")指定读取范围 - 因为仅提取前两行表头数据,使用
collect()不会存在性能问题
内容的提问来源于stack exchange,提问作者Nabia Salman
相关产品推荐
相关产品推荐

