【问题标题】:How to add multiple columns in a spark dataframe using SCALA如何使用 SCALA 在 Spark 数据框中添加多列
【发布时间】:2018-06-15 07:11:00
【问题描述】:

我有一个条件,我必须在一年的 5 个月中添加 5 列(到现有的 DF)。

现有的DF是这样的:

EId EName Esal
1   abhi  1100
2   raj   300
3   nanu  400
4   ram   500

输出应该如下:

EId EName Esal Jan  Feb  March April May  
1   abhi  1100 1100 1100 1100  1100  1100 
2   raj   300  300  300  300   300   300  
3   nanu  400  400  400  400   400   400
4   ram   500  500  500  500   500   500

我可以用 withColumn 一个一个地做到这一点,但这需要很多时间。

有没有一种方法可以让我运行一些循环并继续添加列,直到我的条件用尽为止。

非常感谢。

【问题讨论】:

  • 如何“我可以用withColumn一个一个地做这个,但这需要很多时间。”不同于“有什么方法可以运行一些循环并继续添加列,直到我的条件用尽。”?我看不出有什么区别。

标签: scala apache-spark dataframe


【解决方案1】:

您可以使用foldLeft。您需要为所需的列创建一个List

df.show
+---+----+----+
| id|name| sal|
+---+----+----+
|  1|   A|1100|
+---+----+----+

val list = List("Jan", "Feb" , "Mar", "Apr") // ... you get the idea

list.foldLeft(df)((df, month) => df.withColumn(month , $"sal" ) ).show
+---+----+----+----+----+----+----+
| id|name| sal| Jan| Feb| Mar| Apr|
+---+----+----+----+----+----+----+
|  1|   A|1100|1100|1100|1100|1100|
+---+----+----+----+----+----+----+

所以,基本上发生的事情是您折叠您创建的序列,同时从原始数据框开始并在您继续遍历列表时应用转换。

【讨论】:

  • 该解决方案与 “我可以使用 withColumn 逐一完成此操作,但这需要很多时间。”
  • 不是。它只是更干净一点,我想比背靠背withColumns
  • @JacekLaskowski 不同之处在于我想循环并继续添加列....例如我必须根据条件添加 20 或 30 列,那么是否可以这样做在循环中或以某种方式我不必每次都手动添加它,它应该被迭代?
【解决方案2】:

是的,您可以使用 foldLeft 执行相同操作。FoldLeft 以所需的值从左到右遍历集合中的元素。

因此您可以将所需的列存储在 List() 中。 例如:

val BazarDF = Seq(
        ("Veg", "tomato", 1.99),
        ("Veg", "potato", 0.45),
        ("Fruit", "apple", 0.99),
        ("Fruit", "pineapple", 2.59)
         ).toDF("Type", "Item", "Price")

使用列名和值创建一个列表(例如使用空值)

var ColNameWithDatatype = List(("Jan", lit("null").as("StringType")),
      ("Feb", lit("null").as("StringType")
     ))
var BazarWithColumnDF1 = ColNameWithDatatype.foldLeft(BazarDF) 
  { (tempDF, colName) =>
                     tempDF.withColumn(colName._1, colName._2)
                }

可以看例子Here

【讨论】:

    【解决方案3】:

    请记住,DataFramewithColumn 方法在循环调用时可能会出现性能问题:

    此方法在内部引入投影。因此,多次调用它,例如,通过循环以添加多个列可能会生成大计划,这可能会导致性能问题甚至 StackOverflowException。为避免这种情况,请同时对多列使用 select。

    更安全的方法是使用 select:

    val monthsColumns = months.map { month:String =>
      col("sal").as(month)
    }
    val updatedDf = df.select(df.columns.map(col) ++ monthsColumns: _*)
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      相关资源
      最近更新 更多