如何在Java中对Spark DataFrame执行字符串操作?
嘿,在Java里对Spark DataFrame做字符串操作其实没那么复杂,Spark SQL的functions类提供了一堆现成的工具,我结合你给出的泰坦尼克号风格的DataFrame,给你演示几个最常用的操作场景:
常用字符串操作示例
首先记得静态导入Spark的函数类,这样写代码更清爽:
import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import static org.apache.spark.sql.functions.*;
1. 提取子字符串(比如从Name列拆分姓氏)
你的Name列格式是「姓氏, 头衔. 名字」,可以用substring_index快速提取逗号前的姓氏:
// 提取Name列中的姓氏 Dataset<Row> dfWithLastName = df.withColumn("Last_Name", substring_index(col("Name"), ",", 1)); dfWithLastName.select("Name", "Last_Name").show();
输出会新增Last_Name列,比如第一行就是Braund。
2. 清理/替换字符串(比如整理Ticket列的空格)
Ticket列里有各种空格和特殊格式,用regexp_replace可以批量替换:
// 移除Ticket列中的所有空格 Dataset<Row> dfCleanTicket = df.withColumn("Clean_Ticket", regexp_replace(col("Ticket"), "\\s+", "")); dfCleanTicket.select("Ticket", "Clean_Ticket").show();
比如原Ticket是A/5 21171,处理后会变成A/521171。
3. 大小写转换(统一Sex列格式)
如果Sex列的大小写不统一,可以用upper或lower标准化:
// 将Sex列转为全大写 Dataset<Row> dfUpperSex = df.withColumn("Upper_Sex", upper(col("Sex"))); dfUpperSex.select("Sex", "Upper_Sex").show();
原male会变成MALE,female变成FEMALE。
4. 判断字符串包含关系(检查Ticket是否有特定标识)
用contains可以快速判断某列是否包含指定字符串:
// 检查Ticket列是否包含"A/"前缀,生成布尔列 Dataset<Row> dfHasAPrefix = df.withColumn("Has_A_Prefix", contains(col("Ticket"), "A/")); dfHasAPrefix.select("Ticket", "Has_A_Prefix").show();
第一行的Ticket符合条件,会显示true,其他行根据内容返回false。
5. 处理空值/缺失字符串(填充Cabin列的Null)
针对Cabin列的Null值,用when+isNull组合填充默认值:
// 给Cabin列的Null值填充"Unknown" Dataset<Row> dfFilledCabin = df.withColumn("Filled_Cabin", when(col("Cabin").isNull(), lit("Unknown")).otherwise(col("Cabin")) ); dfFilledCabin.select("Cabin", "Filled_Cabin").show();
原Null的Cabin会被替换成Unknown,已有值的保持不变。
6. 自定义复杂字符串处理(用UDF提取头衔)
如果内置函数满足不了需求,可以写自定义UDF。比如从Name列提取Mr./Mrs./Miss.这类头衔:
import org.apache.spark.sql.api.java.UDF1; import org.apache.spark.sql.types.DataTypes; // 定义UDF:从Name字符串中提取头衔 UDF1<String, String> extractTitleUdf = name -> { if (name == null) return null; String[] nameParts = name.split(", "); if (nameParts.length < 2) return null; String titleSection = nameParts[1]; return titleSection.split("\\.")[0] + "."; }; // 注册UDF到Spark环境 spark.udf().register("extractTitle", extractTitleUdf, DataTypes.StringType); // 使用UDF生成新列 Dataset<Row> dfWithTitle = df.withColumn("Title", callUDF("extractTitle", col("Name"))); dfWithTitle.select("Name", "Title").show();
输出的Title列会是Mr./Mrs./Miss.这类值,完美匹配你的数据格式。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

