我有两个数据框import angular from "angular";
export default angular.module("practice", []).component("app", {
template: "<div>This needs to show up!!</div>"
});
<multipart-config>
<!– 50MB max –>
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
和df1
+---+---+----------+
| n|val| distances|
+---+---+----------+
| 1| 1|0.27308652|
| 2| 1|0.24969208|
| 3| 1|0.21314497|
+---+---+----------+
我想向名为df2
的{{1}}添加一个新列,该列将包含+---+---+----------+
| x1| x2| w|
+---+---+----------+
| 1| 2|0.03103427|
| 1| 4|0.19012526|
| 1| 10|0.26805446|
| 1| 8|0.26825935|
+---+---+----------+
时df1
的{{1}}值的总和
我尝试使用udf,但显然从不同的数据框中选择是行不通的,因为值应该在计算之前确定
gamma
有没有办法在不使用周期的情况下使用w
或df2
进行此操作?
答案 0 :(得分:1)
您无法在udf
内引用DataFrame。正如您所提到的,此问题最好使用join
来解决。
IIUC,您正在寻找类似的内容:
from pyspark.sql import Window
import pyspark.sql.functions as F
df1.alias("L").join(df2.alias("R"), (df1.n == df2.x1) | (df1.n == df2.x2), how="left")\
.select("L.*", F.sum("w").over(Window.partitionBy("n")).alias("gamma"))\
.distinct()\
.show()
#+---+---+----------+----------+
#| n|val| distances| gamma|
#+---+---+----------+----------+
#| 1| 1|0.27308652|0.75747334|
#| 3| 1|0.21314497| null|
#| 2| 1|0.24969208|0.03103427|
#+---+---+----------+----------+
或者如果您对pyspark-sql
语法更加熟悉,可以注册临时表并执行:
df1.registerTempTable("df1")
df2.registerTempTable("df2")
sqlCtx.sql(
"SELECT DISTINCT L.*, SUM(R.w) OVER (PARTITION BY L.n) AS gamma "
"FROM df1 L LEFT JOIN df2 R ON L.n = R.x1 OR L.n = R.x2"
).show()
#+---+---+----------+----------+
#| n|val| distances| gamma|
#+---+---+----------+----------+
#| 1| 1|0.27308652|0.75747334|
#| 3| 1|0.21314497| null|
#| 2| 1|0.24969208|0.03103427|
#+---+---+----------+----------+
<强>解释强>
在这两种情况下,我们都df1
df2
到df1
。这将保留df2
中的所有行,无论是否匹配。
join子句是您在问题中指定的条件。因此x1
中x2
或n
等于n
的所有行都将被加入。
接下来选择左表中的所有行加上我们分组(分区依据)w
并将n
的值相加。对于INSERT INTO Table3 SELECT * FROM Table1;
INSERT INTO Table3 SELECT * FROM Table2;
的每个值,这将获得与连接条件匹配的所有行的总和。
最后,我们只返回不同的行以消除重复。