如何为所有列编写withColumnRenamed并在spark数据框

时间:2017-09-28 10:34:11

标签: scala apache-spark-sql spark-dataframe

您好我有两个文本文件,我必须加入这两个文本文件来创建唯一的文件。 我在spark中使用了数据框来实现这一点。

除了某些字段外,两个文本文件都具有相同的结构。

现在我必须创建数据框并加入两个数据框。

问题1:我们如何加入具有一些额外字段的数据框。 例如,我的架构首先作为TimeStamp提交,但我的第一个dataFrame没有TimeStamp字段。

问题2:在我的代码中,我必须重命名所有列以便在连接后选择列,并且我有29列,所以我必须写29次重命名功能。有没有办法,我可以这样做,而无需写这么多次

问题3:加入后我必须根据某些文件保存输出。 例如,如果StatementTypeCode是BAL,则属于BAL的所有记录将转到一个这样的文件,与map reduce中的自定义分区相同。

这是我试过的latestForEachKey.write.partitionBy("StatementTypeCode")我希望它应该是正确的。

我知道我在一篇文章中提出了这么多问题。我正在学习火花scala,因此在每个语法和每个概念中面临问题。 我希望我的问题很明确。

这是我现在正在做的代码。

    val sqlContext = new org.apache.spark.sql.SQLContext(sc)
        import sqlContext.implicits._

        import org.apache.spark.{ SparkConf, SparkContext }
        import java.sql.{Date, Timestamp}
        import org.apache.spark.sql.Row
        import org.apache.spark.sql.types.{ StructType, StructField, StringType, DoubleType, IntegerType,TimestampType }
        import org.apache.spark.sql.functions.udf

       val schema = StructType(Array(

    StructField("TimeStamp", StringType),
    StructField("LineItem_organizationId", StringType),
    StructField("LineItem_lineItemId", StringType),
    StructField("StatementTypeCode", StringType),
    StructField("LineItemName", StringType),
    StructField("LocalLanguageLabel", StringType),
    StructField("FinancialConceptLocal", StringType),
    StructField("FinancialConceptGlobal", StringType),
    StructField("IsDimensional", StringType),
    StructField("InstrumentId", StringType),
    StructField("LineItemLineItemName", StringType),
    StructField("PhysicalMeasureId", StringType),
    StructField("FinancialConceptCodeGlobalSecondary", StringType),
    StructField("IsRangeAllowed", StringType),
    StructField("IsSegmentedByOrigin", StringType),
    StructField("SegmentGroupDescription", StringType),
    StructField("SegmentChildDescription", StringType),
    StructField("SegmentChildLocalLanguageLabel", StringType),
    StructField("LocalLanguageLabel_languageId", StringType),
    StructField("LineItemName_languageId", StringType),
    StructField("SegmentChildDescription_languageId", StringType),
    StructField("SegmentChildLocalLanguageLabel_languageId", StringType),
    StructField("SegmentGroupDescription_languageId", StringType),
    StructField("SegmentMultipleFundbDescription", StringType),
    StructField("SegmentMultipleFundbDescription_languageId", StringType),
    StructField("IsCredit", StringType),
    StructField("FinancialConceptLocalId", StringType),
    StructField("FinancialConceptGlobalId", StringType),
    StructField("FinancialConceptCodeGlobalSecondaryId", StringType),
    StructField("FFFFAction", StringType)))


       val textRdd1 = sc.textFile("s3://trfsdisu/SPARK/Main.txt")
        val rowRdd1 = textRdd1.map(line => Row.fromSeq(line.split("\\|\\^\\|", -1)))
        var df1 = sqlContext.createDataFrame(rowRdd1, schema).drop("index")

        val textRdd2 = sc.textFile("s3://trfsdisu/SPARK/Incr.txt")
        val rowRdd2 = textRdd2.map(line => Row.fromSeq(line.split("\\|\\^\\|", -1)))
        var df2 = sqlContext.createDataFrame(rowRdd2, schema)

        // df2.show(false) 

        import org.apache.spark.sql.expressions._
        val windowSpec = Window.partitionBy("LineItem_organizationId", "LineItem_lineItemId").orderBy($"TimeStamp".cast(TimestampType).desc) 

        val latestForEachKey = df2.withColumn("rank", rank().over(windowSpec)).filter($"rank" === 1).drop("rank", "TimeStamp")
        .withColumnRenamed("StatementTypeCode", "StatementTypeCode_1").withColumnRenamed("LineItemName", "LineItemName_1").withColumnRenamed("FFAction", "FFAction_1")

  //This is where i need help withColumnRenamed part 


    val df3 = df1.join(latestForEachKey, Seq("LineItem_organizationId", "LineItem_lineItemId"), "outer")
          .select($"LineItem_organizationId", $"LineItem_lineItemId",
            when($"StatementTypeCode_1".isNotNull, $"StatementTypeCode_1").otherwise($"StatementTypeCode").as("StatementTypeCode"),
            when($"LineItemName_1".isNotNull, $"LineItemName_1").otherwise($"LineItemName").as("LineItemName"),
            when($"FFAction_1".isNotNull, $"FFAction_1").otherwise($"FFAction").as("FFAction")).filter(!$"FFAction".contains("D"))

        df3.show()

1 个答案:

答案 0 :(得分:0)

架构部分可以像这样解决

a = ["foo", "bar", "baz", "bar"]
x = "bar"
found = [idx for idx, item in enumerate(a) if item == x]

print(found)