Spark(python):如何“连接”两个仅出现第一次出现的数据帧

时间:2017-09-03 22:49:05

标签: python join dataframe spark-dataframe

我正在寻找pyspark的解决方案,但是对于这个想法/如何在熊猫中解决它也很满意。想象一下,您有两个这样的数据框:

unsigned count_words(char*str)
{
unsigned len, words;

for(len=words=0; *str; str++){
        if(*str == ' ') if(len) {words++; len=0;}
        else len += 1;
        }

if (len) {words++; }
return words;
}

你想获得结果,只有第一次出现的地方才会合并,如下所示:

+----+---+
|name| _2|
+----+---+
|   A| 10|
|   A| 22|
|   A| 30|
|   B|  2|
|   B|  3|
|   D| 14|
+----+---+

+----+----+
|name|   t|
+----+----+
|   A|true|
|   B|true|
|   C|true|
+----+----+

2 个答案:

答案 0 :(得分:0)

您可以在第一个数据帧上使用窗口函数:

首先让我们创建我们的数据帧:

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中的行,这些行始终等于1中的df2

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时不匹配,我们可以使用whenotherwise子句或函数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|
    +----+---+---+-----+

答案 1 :(得分:0)

我相信一个左外连接将会成功。在左外连接后,您必须将null值替换为false

在此处阅读有关左外连接的更多信息:http://spark.apache.org/docs/2.0.0/api/python/pyspark.sql.html#pyspark.sql.DataFrame.join