有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用逗号拆分数据集<Row>上的字符串列,并获取新数据集<Row>

我正在使用Spark(2.0)开发Spark SQL,并使用JavaAPI读取CSV

在CSV文件中有一个双引号、逗号分隔的列。例如:"Express Air,Delivery Truck"

读取CSV并返回数据集的代码:

Dataset<Row> df = spark.read()
                .format("com.databricks.spark.csv")
                .option("inferSchema", "true")
                .option("header", "true")
                .load(filename) 

结果:

+-----+--------------+--------------------------+
|Year |       State  |                Ship Mode |...
+-----+--------------+--------------------------+
|2012 |New York      |Express Air,Delivery Truck|...
|2013 |Nevada        |Delivery Truck            |...
|2013 |North Carolina|Regular Air,Delivery Truck|...
+-----+--------------+--------------------------+

但是,我想将Shop Mode拆分为Mode1Mode2列,并作为数据集返回

+-----+--------------+--------------+---------------+
|Year |       State  |     Mode1    |         Mode2 |...
+-----+--------------+--------------+---------------+
|2012 |New York      |Express Air   |Delivery Truck |...
|2013 |Nevada        |Delivery Truck|null           |...
|2013 |North Carolina|Regular Air   |Delivery Truck |...
+-----+--------------+--------------+---------------+

有什么方法可以使用Java Spark做到这一点吗

我尝试使用MapFunction,但call()方法没有返回行。 Ship Mode将是动态的,即CSV可能包含一个或两个装运模式

谢谢


共 (2) 个答案

  1. # 1 楼答案

    您可以使用selectExpr,这是一种接受SQL表达式的select变体,如下所示:

    df.selectExpr("Year","State","split(Ship Mode, ',')[0] as Mode1","split(Ship Mode, ',')[1] as Mode2");
    

    结果是一个行的数据集

  2. # 2 楼答案

    我们可以:

    • 定义一个用户定义函数(UDF)以仅执行一次拆分操作
    • 使用select表达式将拆分的列映射为两个新列

    例如:

    import org.apache.spark.sql.functions._
    import org.apache.spark.sql.{Column, Row}
    
    val splitter = udf((str: String) => {
      val splitted = str.split(",").lift
      Array(splitted(0), splitted(1))
    })
    
    val dfShipMode = df.select($"year",$"state", splitter($"shipMode") as "modes")
                       .select($"year", $"state", $"modes"(0) as "mode1", $"modes"(1) as "mode2")