迭代 Spark 数据集的行并在 Java API 中应用操作
Iterating rows of a Spark Dataset and applying operations in Java API
Spark 新手 (2.4.x) 并使用 Java API (not斯卡拉!!!)
我有一个从 CSV 文件读入的 Dataset
。它有一个模式(命名列),如下所示:
id (integer) | name (string) | color (string) | price (double) | enabled (boolean)
示例行:
23 | "hotmeatballsoup" | "blue" | 3.95 | true
数据集中有很多(数万)行。我想使用适当的 Java/Spark API 编写一个表达式,滚动浏览每一行并对每一行应用以下两个操作:
- 如果价格是
null
,默认为0.00
;然后
- 如果颜色栏值为"red",则将
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|
+---+---------------+-----+-----+-------+
在 class 声明之前导入 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|
+---+---------------+-----+-----+-------+
Spark 新手 (2.4.x) 并使用 Java API (not斯卡拉!!!)
我有一个从 CSV 文件读入的 Dataset
。它有一个模式(命名列),如下所示:
id (integer) | name (string) | color (string) | price (double) | enabled (boolean)
示例行:
23 | "hotmeatballsoup" | "blue" | 3.95 | true
数据集中有很多(数万)行。我想使用适当的 Java/Spark API 编写一个表达式,滚动浏览每一行并对每一行应用以下两个操作:
- 如果价格是
null
,默认为0.00
;然后 - 如果颜色栏值为"red",则将
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|
+---+---------------+-----+-----+-------+
在 class 声明之前导入 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|
+---+---------------+-----+-----+-------+