Spark中Dataset方法详解

一、数据清洗核心方法

1. 处理缺失值
方法 说明 示例代码
na().drop() 删除包含空值的行 Dataset cleaned = dataset.na().drop();
na().fill(value) 用指定值填充所有空值 Dataset filled = dataset.na().fill(0);
na().fill(Map) 按列填充不同值 Map fills = new HashMap<>(); fills.put("age", 0); dataset.na().fill(fills);
2. 去重处理
方法 说明 示例代码
dropDuplicates() 删除完全重复的行 Dataset unique = dataset.dropDuplicates();
dropDuplicates(colNames) 根据指定列去重 Dataset unique = dataset.dropDuplicates(new String[]{"id"});
3. 过滤无效数据
方法 说明 示例代码
filter(condition) 根据条件过滤行 Dataset valid = dataset.filter(col("age").gt(0));
where(condition) filter Dataset valid = dataset.where("salary > 1000");
4. 类型转换
方法 说明 示例代码
withColumn(colName, expr) 转换列类型或计算新列 Dataset converted = dataset.withColumn("age", col("age").cast("int"));
cast(DataType) 强制类型转换 col("timestamp").cast(DataTypes.TimestampType)
5. 列操作
方法 说明 示例代码
select(cols) 选择特定列 Dataset selected = dataset.select(col("name"), col("age"));
withColumnRenamed(old, new) 重命名列 Dataset renamed = dataset.withColumnRenamed("oldName", "newName");
drop(colName) 删除列 Dataset reduced = dataset.drop("unusedColumn");
6. 字符串处理
方法 说明 示例代码
regexp_replace() 正则替换 functions.regexp_replace(col("email"), "@.*", "")
trim() 去除首尾空格 col("name").trim()
substr(start, length) 截取子字符串 col("phone").substr(0, 3)

二、Dataset 核心操作方法

1. 数据加载与保存
方法 说明 示例代码
read().csv(path) 读取 CSV 文件 Dataset df = spark.read().csv("hdfs:///input.csv");
write().parquet(path) 保存为 Parquet 格式 df.write().parquet("hdfs:///output.parquet");
write().jdbc(...) 写入关系型数据库 .option("url", "jdbc:mysql://...") .option("dbtable", "table")
2. 聚合操作
方法 说明 示例代码
groupBy(cols) 按列分组 GroupedData grouped = df.groupBy("department");
agg(exprs) 聚合计算 grouped.agg(avg("salary"), max("age"));
3. 数据转换
方法 说明 示例代码
join(otherDataset, condition) 表连接 df1.join(df2, df1.col("id").equalTo(df2.col("id")));
union(otherDataset) 合并数据集 Dataset combined = df1.union(df2);
4. 数据探查
方法 说明 示例代码
show() 打印前 N 行数据 df.show(10);
printSchema() 打印 Schema df.printSchema();
describe(cols) 统计数值列的基本信息 df.describe("age", "salary").show();

三、完整数据清洗示例

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import static org.apache.spark.sql.functions.*;
​
public class DataCleaningExample {
    public static void main(String[] args) {
        SparkSession spark = SparkSession.builder()
                .appName("Data Cleaning Demo")
                .master("local[*]")
                .getOrCreate();
​
        // 1. 读取原始数据
        Dataset rawData = spark.read()
                .option("header", true)
                .option("inferSchema", true)
                .csv("hdfs:///input.csv");
​
        // 2. 数据清洗流程
        Dataset cleanedData = rawData
                // 处理空值: 删除全空行
                .na().drop("all")
                // 填充特定列空值
                .na().fill(0, new String[]{"age"})
                // 过滤无效年龄
                .filter(col("age").geq(0).and(col("age").leq(100)))
                // 类型转换
                .withColumn("birth_year", 
                    functions.lit(2023).minus(col("age")).cast("int"))
                // 字符串处理
                .withColumn("name", trim(col("name")))
                // 去重
                .dropDuplicates(new String[]{"id"})
                // 选择最终列
                .select("id", "name", "age", "birth_year");
​
        // 3. 保存清洗结果
        cleanedData.write()
                .mode("overwrite")
                .parquet("hdfs:///cleaned_data");
​
        spark.stop();
    }
}

四、性能优化技巧

  1. 分区策略

    // 调整读取分区数
    spark.read().option("basePath", "/data")
        .csv("hdfs:///input_*.csv")
        .repartition(200);
    ​
    // 按列分区保存
    cleanedData.write()
        .partitionBy("year", "month")
        .parquet("hdfs:///partitioned_data");

  2. 缓存机制

    Dataset cachedDF = df.cache(); // MEMORY_AND_DISK

  3. 广播变量

    List validCountries = Arrays.asList("US", "CN", "EU");
    Broadcast> broadcastVar = spark.sparkContext().broadcast(validCountries);
    df.filter(col("country").isin(broadcastVar.value()));

  4. 并行度控制

    park.conf().set("spark.sql.shuffle.partitions", "200");


五、常见问题处理

问题 解决方案
内存不足 (OOM) 增加 Executor 内存:spark.executor.memory=8g
数据倾斜 使用 repartitionsalt 技术分散热点数据
类型转换失败 使用 try_cast 或先过滤无效数据
字符串编码问题 指定编码格式:.option("encoding", "UTF-8")

你可能感兴趣的:(Spark+Hadoop学习,spark,ajax,java,分布式)