【问题标题】:Merge two columns in a spark dataset using Java使用 Java 合并 spark 数据集中的两列
【发布时间】:2017-11-22 13:10:50
【问题描述】:

我想合并 apache spark 数据集中的两列。 我尝试了以下方法,但没有奏效,有人可以提出解决方案吗?

        Dataset<Row> df1 = spark.read().json("src/test/resources/DataSets/DataSet.json");
        Dataset<Row> df1Map = df1.select(functions.array("beginTime", "endTime"));
    df1Map.show();

输入的DataSet.json如下:

{"IPsrc":"abc", "IPdst":"def", "beginTime": 1, "endTime":1}
{"IPsrc":"def", "IPdst":"abc", "beginTime": 2, "endTime":2}
{"IPsrc":"abc", "IPdst":"def", "beginTime": 3, "endTime":3}
{"IPsrc":"def", "IPdst":"abc", "beginTime": 4, "endTime":4}

请注意我在 JAVA 8 中这样做

以上导致错误如下:

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'beginTime': was expecting ('true', 'false' or 'null')
at [Source: beginTime; line: 1, column: 19]

at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1581)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:533)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2462)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1621)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:689)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3776)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3721)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726)
at org.json4s.jackson.JsonMethods$class.parse(JsonMethods.scala:20)
at org.json4s.jackson.JsonMethods$.parse(JsonMethods.scala:50)
at org.apache.spark.sql.types.DataType$.fromJson(DataType.scala:104)
at org.apache.spark.sql.types.DataType.fromJson(DataType.scala)

df1.show()的初始表输出如下:

+-----+-----+---------+-------+
|IPdst|IPsrc|beginTime|endTime|
+-----+-----+---------+-------+
|  def|  abc|        1|      1|
|  abc|  def|        2|      2|
|  def|  abc|        3|      3|
|  abc|  def|        4|      4|
+-----+-----+---------+-------+

df1的架构如下:

root
 |-- IPdst: string (nullable = true)
 |-- IPsrc: string (nullable = true)
 |-- beginTime: long (nullable = true)
 |-- endTime: long (nullable = true)

【问题讨论】:

  • 您能否详细说明什么不起作用:您收到错误或意外输出?另请提供输出/错误。
  • @AbhishekBansal - 用细节更新了问题
  • 顺便说一句。我使用的是 Dataset 而不是数据框,另外我使用以下“concat”函数答案中建议的方法得到了相同的错误
  • 如何加载 df1 数据集?可以贴一下代码吗?
  • 详情请查看更新后的问题

标签: java apache-spark-sql apache-spark-dataset


【解决方案1】:

如果你想连接两列,你可以这样做:

Dataset<Row> df1Map = df1.select(functions.concat(df1.col("beginTime"), df1.col("endTime")));
df1Map.show();

编辑: 我试过了,它奏效了: 这是我的代码:

SparkSession spark = SparkSession
            .builder()
            .master("local")
            .appName("SO")
            .getOrCreate();

Dataset<Row> df1 = spark.read().json("src/main/resources/json/Dataset.json");
df1.printSchema();
df1.show();

Dataset<Row> df1Map = df1.select(functions.array("beginTime", "endTime"));
df1Map.show();

【讨论】:

  • 理想情况下,我想创建一个包含两列的数组。但是,我尝试了您的方法并收到以下错误:com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'beginTime': was expected ('true', 'false' or 'null') at [Source: beginTime;行:1,列:19]
  • 感谢您的尝试,我发现错误似乎不是从 intelliJ 的单元测试中运行,但可以正常工作。
  • 您能否告诉我如何保留所有其他列?我只想合并这两个,但其余的保持原样,我不知道架构提前,所以我不知道所有列的名称
  • 另外我如何重命名这个新数组(beginTime,endTime)列?
  • 好的,你找到了!你可以用.withColumn() 来做到这一点:Dataset&lt;Row&gt; df1Map = df1.withColumn("begin_end_time", functions.array("beginTime", "endTime"));
【解决方案2】:

你可以试试这个

Dataset<Row> df1Map = df1.withColumn("begin_end_time", concat(col("beginTime"), lit(" - "), (col("endTime")) );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2018-12-19
    • 2019-07-30
    • 2022-11-11
    相关资源
    最近更新 更多