我正在寻找pyspark的解决方案,但对这个想法/如何在熊猫中解决它会感到满意。想象一下您有两个数据帧喜欢以下方式:
+----+---+
|name| _2|
+----+---+
| A| 10|
| A| 22|
| A| 30|
| B| 2|
| B| 3|
| D| 14|
+----+---+
+----+----+
|name| t|
+----+----+
| A|true|
| B|true|
| C|true|
+----+----+
您想获得结果,只有第一次出现被合并,类似的东西:
+----+---+-----+
|name| _2| t|
+----+---+-----+
| A| 10| true|
| A| 22|false|
| A| 30|false|
| B| 2| true|
| B| 3|false|
| D| 14|false|
+----+---+-----+
您可以在第一个dataframe上使用窗口函数:
首先,让我们创建我们的dataFrames:
df1 = spark.createDataFrame(sc.parallelize([["A",10],["A",22],["A",30],["B",2],["B",3],["D",14]]), ["name","_2"])
df2 = spark.createDataFrame(sc.parallelize([["A",True],["B",True],["C",True]]), ["name","t"])
接下来,我们将添加一个"rn"
列以枚举df1
中的行,该行始终等于df2
中的1
:
from pyspark.sql import Window
import pyspark.sql.functions as psf
w = Window.partitionBy("name").orderBy("_2")
df1 = df1.withColumn("rn", psf.row_number().over(w))
df2 = df2.withColumn("rn", psf.lit(1))
+----+---+---+
|name| _2| rn|
+----+---+---+
| B| 2| 1|
| B| 3| 2|
| D| 14| 1|
| A| 10| 1|
| A| 22| 2|
| A| 30| 3|
+----+---+---+
+----+----+---+
|name| t| rn|
+----+----+---+
| A|true| 1|
| B|true| 1|
| C|true| 1|
+----+----+---+
我们现在可以在列上使用left join
"name", "rn"
:
df = df1.join(df2, ["name", "rn"], "leftouter")
+----+---+---+----+
|name| rn| _2| t|
+----+---+---+----+
| A| 3| 30|null|
| A| 1| 10|true|
| A| 2| 22|null|
| B| 1| 2|true|
| D| 1| 14|null|
| B| 2| 3|null|
+----+---+---+----+
我们希望"t"
列为False
不匹配时null
,我们可以使用when
,otherwise
子句或函数coalesce
:
df = df.withColumn("t", psf.coalesce(df.t, psf.lit(False)))
+----+---+---+-----+
|name| rn| _2| t|
+----+---+---+-----+
| A| 3| 30|false|
| A| 1| 10| true|
| A| 2| 22|false|
| B| 1| 2| true|
| D| 1| 14|false|
| B| 2| 3|false|
+----+---+---+-----+
我相信左外的联接将do the Trick。左外部加入后,您必须用false
替换null
值。
在此处阅读有关左外外线的更多信息:http://spark.apache.org/docs/2.0.0/api/python/python/pyspark.sql.html.html#pyspark.sql.dataframe.join.join/p>