我正在寻找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|
+----+----+
答案 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
时不匹配,我们可以使用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|
+----+---+---+-----+
答案 1 :(得分:0)
我相信一个左外连接将会成功。在左外连接后,您必须将null
值替换为false
。
在此处阅读有关左外连接的更多信息:http://spark.apache.org/docs/2.0.0/api/python/pyspark.sql.html#pyspark.sql.DataFrame.join