Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数据帧透视-Spark SQL_Java_Scala_Apache Spark_Apache Spark Sql_Pivot - Fatal编程技术网

Java 数据帧透视-Spark SQL

Java 数据帧透视-Spark SQL,java,scala,apache-spark,apache-spark-sql,pivot,Java,Scala,Apache Spark,Apache Spark Sql,Pivot,我有一个包含以下内容的数据框: TradeId |来源 ABC |“333.12320170605美元,-789.44420170605英镑1234.56720150602” 我想将这些数据转换为以下内容 TradeId | CCY | PV ABC |美元| 333.123 ABC |美元|-789.444 美国银行1234.567英镑 “源”列中CCY | PV |日期三元组的数量不是固定的。我可以在ArrayList中完成,但这需要在JVM中加载数据,这就破坏了Spark的全部功能 假

我有一个包含以下内容的数据框:

TradeId |来源
ABC |“333.12320170605美元,-789.44420170605英镑1234.56720150602”
我想将这些数据转换为以下内容

TradeId | CCY | PV
ABC |美元| 333.123
ABC |美元|-789.444
美国银行1234.567英镑
“源”列中CCY | PV |日期三元组的数量不是固定的。我可以在ArrayList中完成,但这需要在JVM中加载数据,这就破坏了Spark的全部功能

假设我的数据框如下所示:

DataFrame tradesSnap = this.loadTradesSnap(reportRequest);
String tempTable = getTempTableName();
tradesSnap.registerTempTable(tempTable);
tradesSnap = tradesSnap.sqlContext().sql("SELECT TradeId, Source FROM " + tempTable);

您试图实现的目标看起来更像是
flatMap
,而不是旋转

简单地说,通过在
数据集上使用
flatMap
,可以将一个函数(
map
)应用于每一行,该函数本身将生成一系列行。然后将每组行连接成单个序列(
flat

以下程序显示了这一想法:

import org.apache.spark.sql.SparkSession

case class Input(TradeId: String, Source: String)

case class Output(TradeId: String, CCY: String, PV: String, Date: String)

object FlatMapExample {

  // This function will produce more rows of output for each line of input
  def splitSource(in: Input): Seq[Output] =
    in.Source.split("\\|", -1).map {
      source =>
        println(source)
        val Array(ccy, pv, date) = source.split(",", -1)
        Output(in.TradeId, ccy, pv, date)
    }

  def main(args: Array[String]): Unit = {

    // Initialization and loading
    val spark = SparkSession.builder().master("local").appName("pivoting-example").getOrCreate()
    import spark.implicits._
    val input = spark.read.options(Map("sep" -> "|", "header" -> "true")).csv(args(0)).as[Input]

    // For each line in the input, split the source and then 
    // concatenate each "sub-sequence" in a single `Dataset`
    input.flatMap(splitSource).show
  }

}
根据您的输入,这将是输出:

+-------+---+--------+--------+
|TradeId|CCY|      PV|    Date|
+-------+---+--------+--------+
|    ABC|USD| 333.123|20170605|
|    ABC|USD|-789.444|20170605|
|    ABC|GBP|1234.567|20150602|
+-------+---+--------+--------+

如果需要,您现在可以获取结果并将其保存到CSV中。

您尝试实现的目标看起来更像是平面地图,而不是旋转

简单地说,通过在
数据集上使用
flatMap
,可以将一个函数(
map
)应用于每一行,该函数本身将生成一系列行。然后将每组行连接成单个序列(
flat

以下程序显示了这一想法:

import org.apache.spark.sql.SparkSession

case class Input(TradeId: String, Source: String)

case class Output(TradeId: String, CCY: String, PV: String, Date: String)

object FlatMapExample {

  // This function will produce more rows of output for each line of input
  def splitSource(in: Input): Seq[Output] =
    in.Source.split("\\|", -1).map {
      source =>
        println(source)
        val Array(ccy, pv, date) = source.split(",", -1)
        Output(in.TradeId, ccy, pv, date)
    }

  def main(args: Array[String]): Unit = {

    // Initialization and loading
    val spark = SparkSession.builder().master("local").appName("pivoting-example").getOrCreate()
    import spark.implicits._
    val input = spark.read.options(Map("sep" -> "|", "header" -> "true")).csv(args(0)).as[Input]

    // For each line in the input, split the source and then 
    // concatenate each "sub-sequence" in a single `Dataset`
    input.flatMap(splitSource).show
  }

}
根据您的输入,这将是输出:

+-------+---+--------+--------+
|TradeId|CCY|      PV|    Date|
+-------+---+--------+--------+
|    ABC|USD| 333.123|20170605|
|    ABC|USD|-789.444|20170605|
|    ABC|GBP|1234.567|20150602|
+-------+---+--------+--------+
如果您愿意,您现在可以获取结果并将其保存到CSV中。

如果您阅读,它会说
“pivot是一个聚合,其中一个(或多个在一般情况下)分组列的不同值被转换到各个列中。”
我想这不是您想要的

我建议您使用并获得所需的最终输出。考虑到您拥有的是
dataframe
,您可以执行以下操作

+-------+----------------------------------------------------------------+
|TradeId|Source                                                          |
+-------+----------------------------------------------------------------+
|ABC    |USD,333.123,20170605|USD,-789.444,20170605|GBP,1234.567,20150602|
+-------+----------------------------------------------------------------+
您可以使用
explode
split
withColumn
执行以下操作,以获得所需的输出

val explodedDF = dataframe.withColumn("Source", explode(split(col("Source"), "\\|")))
val finalDF = explodedDF.withColumn("CCY", split($"Source", ",")(0))
  .withColumn("PV", split($"Source", ",")(1))
  .withColumn("Date",  split($"Source", ",")(2))
  .drop("Source")

finalDF.show(false)
最终输出为

+-------+---+--------+--------+
|TradeId|CCY|PV      |Date    |
+-------+---+--------+--------+
|ABC    |USD|333.123 |20170605|
|ABC    |USD|-789.444|20170605|
|ABC    |GBP|1234.567|20150602|
+-------+---+--------+--------+
我希望这能解决您的问题

如果您阅读,它会说,
“pivot是一个聚合,其中一个(在一般情况下是多个)分组列的不同值被转换为单独的列。”
我想这不是您想要的

我建议您使用并获得所需的最终输出。考虑到您拥有的是
dataframe
,您可以执行以下操作

+-------+----------------------------------------------------------------+
|TradeId|Source                                                          |
+-------+----------------------------------------------------------------+
|ABC    |USD,333.123,20170605|USD,-789.444,20170605|GBP,1234.567,20150602|
+-------+----------------------------------------------------------------+
您可以使用
explode
split
withColumn
执行以下操作,以获得所需的输出

val explodedDF = dataframe.withColumn("Source", explode(split(col("Source"), "\\|")))
val finalDF = explodedDF.withColumn("CCY", split($"Source", ",")(0))
  .withColumn("PV", split($"Source", ",")(1))
  .withColumn("Date",  split($"Source", ",")(2))
  .drop("Source")

finalDF.show(false)
最终输出为

+-------+---+--------+--------+
|TradeId|CCY|PV      |Date    |
+-------+---+--------+--------+
|ABC    |USD|333.123 |20170605|
|ABC    |USD|-789.444|20170605|
|ABC    |GBP|1234.567|20150602|
+-------+---+--------+--------+

我希望这能解决你的问题

是的,我最终也找到了这个选择。它更容易理解,甚至可以将它添加到我最初的select查询中。很高兴听到@Archilles。谢谢你的接受和支持:)是的,我最终也找到了这个选择。它更容易理解,甚至可以将它添加到我最初的select查询中。很高兴听到@Archilles。感谢您的接受和投票:)