我有一个如下所示的DataFrame。我需要根据现有列创建一个新列。
col1 col2
a 1
a 2
b 1
c 1
d 1
d 2
输出数据框看起来像这样
col1 col2 col3 col4
a 1 1 2
a 2 1 2
b 1 0 1
c 1 0 1
d 1 1 2
d 2 1 2
我用来查找col3的逻辑是如果col1的数量> 1 和 col4是col2的最大值。
我熟悉如何在sql中执行此操作。但是很难找到数据帧DSL的解决方案。任何帮助,将不胜感激。感谢
答案 0 :(得分:2)
groupBy col1并汇总以获得count和max。然后,您可以join将其与原始数据帧一起返回,以获得所需的结果
val df2 = df1.groupBy("col1").agg(count() as col3, max("col2") as col4)
val df3 = df1.join(df2, "col1")
答案 1 :(得分:2)
spark df有被称为的属性 的 withColumn 强> 您可以根据需要添加任意数量的派生列。但是该列未添加到现有DF中,而是创建一个添加了列的新DF。
e.g。向数据添加静态日期
val myFormattedData = myData.withColumn("batchdate",addBatchDate(myData("batchdate")))
val addBatchDate = udf { (BatchDate: String) => "20160101" }
答案 2 :(得分:1)
要添加col3,您可以使用withcolumn + when / otherwise:
val df2 = df.withColumn("col3",when($"col2" > 1, 1).otherwise(0))
要添加col4,已经提到的groupBy / max + join应该完成这项工作:
val df3 = df2.join(df.groupBy("col1").max("col2"), "col1")
答案 3 :(得分:0)
要在没有连接的情况下实现此目的,您需要使用count
和max
作为窗口函数。这需要使用Window
创建一个窗口,并告诉count
和max
对该窗口进行操作。
from pyspark.sql import Window, functions as fn
df = sc.parallelize([
{'col1': 'a', 'col2': 1},
{'col1': 'a', 'col2': 2},
{'col1': 'b', 'col2': 1},
{'col1': 'c', 'col2': 1},
{'col1': 'd', 'col2': 1},
{'col1': 'd', 'col2': 2}
]).toDF()
col1_window = Window.partitionBy('col1')
df = df.withColumn('col3', fn.when(fn.count('col1').over(col1_window) > 1, 1).otherwise(0))
df = df.withColumn('col4', fn.max('col2').over(col1_window))
df.orderBy(['col1', 'col2']).show()