使用Scala将列分配给Spark Dataframe中的其他列

时间:2019-03-09 08:07:47

标签: apache-spark

我一直在寻找一个很好的问题,以提高我的Scala技能和答案:Extract a column value and assign it to another column as an array in spark dataframe

我按如下所示创建了修改后的代码,但仍然存在一些问题:

name, age

它有效,但是:

  • 我注意到b列被放置了两次。
  • 我也可以在第二条语句中的a列中输入相同的结果。例如。那是什么意思呢?
  

df.withColumn(“ X”,myfun_udf(col(“ a”)))。show

  • 如果我输入col ID,那么它将为空。
  • 那么,我想知道为什么要输入第二个col吗?
  • 又如何使它对所有列通用?

所以,这是我在其他地方查看过的代码,但是我缺少一些东西。

1 个答案:

答案 0 :(得分:1)

您显示的代码没有多大意义:

  • 它不可伸缩-在最坏的情况下,每行的大小与大小成比例
  • 您已经知道它根本不需要参数。
  • 在编写时(在2016年12月23日已发布Spark 1.6和2.0的情况下,udf不需要udf
  • 如果您仍然想使用udf空变量就足够了

总体而言,这只是为OP提供服务的另一个令人费解和误导性的答案。我会忽略(或vote accordingly)并继续前进。

那怎么办呢?

  • 如果您有本地列表,并且确实要使用udf。对于单个序列,请结合使用nullaryval uniqueBVal: Seq[Int] = ??? val addUniqueBValCol = udf(() => uniqueBVal) df.withColumn("X", addUniqueBValCol()) 函数:

    import scala.reflect.runtime.universe.TypeTag
    
    def addLiteral[T : TypeTag](xs: Seq[T]) = udf(() => xs)
    
    val x = addLiteral[Int](uniqueBVal)
    df.withColumn("X", x())
    

    推广到:

    udf
  • 最好不要使用import org.apache.spark.sql.functions._ df.withColumn("x", array(uniquBVal map lit: _*))

    import org.apache.spark.sql.expressions.Window
    
    val w = Window.rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)
    df.select($"*" +: df.columns.map(c => collect_set(c).over(w).alias(s"${c}_unique")): _*)
    
  • 截至

      

    又如何使它对所有列通用?

    正如开头提到的,整个概念很难辩护。两种窗口功能(完全无法扩展)

    val uniqueValues = df.select(
      df.columns map (c => collect_set(col(c)).alias(s"${c}_unique")):_*
    )
    df.crossJoin(uniqueValues)
    

    或以聚合方式交叉连接(大多数情况下不可扩展)

    DateTimeTimeZone start = new DateTimeTimeZone
    {
        TimeZone = TimeZoneInfo.Local.Id,
        DateTime = dateTimePicker1.Value.ToString("o"),
    };
    
    DateTimeTimeZone end = new DateTimeTimeZone
    {
        TimeZone = TimeZoneInfo.Local.Id,
        DateTime = dateTimePicker2.Value.ToString("o"),
    };
    
    Location location = new Location
    {
        DisplayName = "Thuis",
    };
    
    byte[] contentBytes = System.IO.File
        .ReadAllBytes(@"C:\test\sample.pdf");
    
    var ev = new Event();
    
    FileAttachment fa = new FileAttachment
    {
        ODataType = "#microsoft.graph.fileAttachment",
        ContentBytes = contentBytes,
        ContentType = "application/pdf",
        Name = "sample.pdf",
        IsInline = false,
        Size = contentBytes.Length
    };
    
    ev.Attachments = new EventAttachmentsCollectionPage();
    ev.Attachments.Add(fa);
    
    ev.Start = start;
    ev.End = end;
    ev.IsAllDay = false;
    ev.Location = location;
    ev.Subject = textBox2.Text;
    
    var response = await graphServiceClient
        .Users["user@docned.nl"]
        .Calendar
        .Events
        .Request()
        .AddAsync(ev);
    

    尽管如此,通常-您必须重新考虑您的方法,如果这种方法可以应用于实际应用程序中,除非您确定不能知道列的基数很小并且具有严格的上限。

带走消息是-不要相信随机人在互联网上发布的随机代码。其中一个。