迭代Spark数据集的行并在JavaAPI中应用操作

迭代Spark数据集的行并在JavaAPI中应用操作,java,apache-spark,apache-spark-dataset,Java,Apache Spark,Apache Spark Dataset,新加入Spark 2.4.x,使用JavaAPI而不是Scala 我有一个从CSV文件中读取的数据集。它有一个名为列的模式,如下所示: id (integer) | name (string) | color (string) | price (double) | enabled (boolean) 示例行: 23 | "hotmeatballsoup" | "blue" | 3.95 | true 数据集中有成千上万行。我想使用适当的Java/Spark API编写一个表达

新加入Spark 2.4.x,使用JavaAPI而不是Scala

我有一个从CSV文件中读取的数据集。它有一个名为列的模式,如下所示:

id (integer)  |  name (string)  |  color (string)  |  price (double)  |  enabled (boolean)
示例行:

23 | "hotmeatballsoup" | "blue" | 3.95 | true
数据集中有成千上万行。我想使用适当的Java/Spark API编写一个表达式,滚动每一行,并对每一行应用以下两个操作:

如果价格为空,则默认为0.00;然后 如果颜色列值为红色,则在价格中添加2.55 因为我对Spark如此陌生,我甚至不知道从哪里开始!到目前为止,我最好的尝试肯定是错误的,但我想这至少是一个起点:

Dataset csvData = sparkSession.read()
    .format("csv")
    .load(fileToLoad.getAbsolutePath());

// ??? get rows somehow
Seq<Seq<String>> csvRows = csvData.getRows(???, ???);

// now how to loop through rows???
for (Seq<String> row : csvRows) {
    // how apply two operations specified above???
    if (row["price"] == null) {
        row["price"] = 0.00;
    }

    if (row["color"].equals("red")) {
        row["price"] = row["price"] + 2.55;
    }
}

有人能帮我朝正确的方向走吗?

你可以使用spark sql api来实现它。还可以使用DataFrameNaFunctions中的.fill将空值替换为值。否则,您可以将Dataframe转换为Dataset,并在.map中执行这些步骤,但在这种情况下,sql api更好、更高效

+---+---------------+-----+-----+-------+
| id|           name|color|price|enabled|
+---+---------------+-----+-----+-------+
| 23|hotmeatballsoup| blue| 3.95|   true|
| 24|            abc|  red|  1.0|   true|
| 24|            abc|  red| null|   true|
+---+---------------+-----+-----+-------+
在类声明之前导入sql函数:

import static org.apache.spark.sql.functions.*;
sql api:

df.select(
        col("id"), col("name"), col("color"),
        when(col("color").equalTo("red").and(col("price").isNotNull()), col("price").plus(2.55))
        .when(col("color").equalTo("red").and(col("price").isNull()), 2.55)
        .otherwise(col("price")).as("price")
        ,col("enabled")
).show();
或使用临时视图和sql查询:

df.createOrReplaceTempView("df");
spark.sql("select id,name,color, case when color = 'red' and price is not null then (price + 2.55) when color = 'red' and price is null then 2.55 else price end as price, enabled from df").show();
输出:

+---+---------------+-----+-----+-------+
| id|           name|color|price|enabled|
+---+---------------+-----+-----+-------+
| 23|hotmeatballsoup| blue| 3.95|   true|
| 24|            abc|  red| 3.55|   true|
| 24|            abc|  red| 2.55|   true|
+---+---------------+-----+-----+-------+