错误:连接中缺少已解决的属性

Posted

技术标签:

【中文标题】错误:连接中缺少已解决的属性【英文标题】:Error: Resolved attributes missing in join 【发布时间】:2020-08-27 09:21:26 【问题描述】:

我正在使用 pyspark 对两个表执行 join 的操作,这些表具有相对复杂的连接条件(在连接条件中使用大于/小于)。这工作正常,但只要我在加入前添加 fillna 命令就会崩溃。

代码如下所示:

join_cond = [
    df_a.col1 == df_b.colx,
    df_a.col2 == df_b.coly,
    df_a.col3 >= df_b.colz
]

df = (
    df_a
    .fillna('NA', subset=['col1'])
    .join(df_b, join_cond, 'left')
)

这会导致如下错误:

org.apache.spark.sql.AnalysisException: col1#6488,col2#4766,col3#4768,colx 中缺少已解决的属性 col1#4765 #4823,coly#4830,colz#4764 in operator !Join LeftOuter, (((col1#4765 = colx#4823) && (col2#4766 = coly#4830)) && (col3#4768 >= colz#4764))。具有相同名称的属性出现在操作中:col1。请检查是否使用了正确的属性。

在执行fillna 之后,spark 似乎不再识别col1。 (如果我将其注释掉,则不会出现错误。)问题是我确实需要该声明。 (总的来说,我已经大大简化了这个例子。)

我查看了this question,但这些答案对我不起作用。具体来说,在 fillna 之后使用 .alias('a') 不起作用,因为 spark 无法识别连接条件中的 a

有人可以:

准确解释为什么会发生这种情况以及我以后如何避免这种情况? 请告诉我解决方法?

提前感谢您的帮助。

【问题讨论】:

修改了这么多列,搞不清楚。 【参考方案1】:

发生了什么?

为了“替换”空值,创建了一个包含新列的新数据框。这些新列与旧列具有相同的名称,但实际上是全新的 Spark 对象。在Scala code 中,您可以看到“更改”列是新创建的列,而原始列是dropped。

查看此效果的一种方法是在替换空值之前和之后在数据帧上调用explain:

df_a.explain()

打印

== Physical Plan ==
*(1) Project [_1#0L AS col1#6L, _2#1L AS col2#7L, _3#2L AS col3#8L]
+- *(1) Scan ExistingRDD[_1#0L,_2#1L,_3#2L]

同时

df_a.fillna(42, subset=['col1']).explain()

打印

== Physical Plan ==
*(1) Project [coalesce(_1#0L, 42) AS col1#27L, _2#1L AS col2#7L, _3#2L AS col3#8L]
+- *(1) Scan ExistingRDD[_1#0L,_2#1L,_3#2L]

两个计划都包含一个名为col1 的列,但在第一种情况下,内部表示称为col1#6L,而第二种情况称为col1#27L

当连接条件df_a.col1 == df_b.colx 现在与列col1#6L 关联时,如果只有列col1#27L 是左表的一部分,则连接将失败。

如何解决问题?

显而易见的方法是在连接条件定义之前移动 `fillna` 操作:
df_a = df_a.fillna('NA', subset=['col1'])
join_cond = [
    df_a.col1 == df_b.colx,
[...]

如果这是不可能的或不希望的,您可以更改连接条件。除了使用数据框 (df_a.col1) 中的列之外,您还可以使用 col 函数使用与任何数据框不关联的列。此列仅根据其名称起作用,因此在数据框中替换该列时会忽略:

from pyspark.sql import functions as F
join_cond = [
    F.col("col1") == df_b.colx,
    df_a.col2 == df_b.coly,
    df_a.col3 >= df_b.colz
]

第二种方法的缺点是两个表中的列名必须是唯一的。

【讨论】:

绝妙的答案!谢谢你。这澄清了很多幕后发生的事情。

以上是关于错误:连接中缺少已解决的属性的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 自联接错误“缺少已解决的属性”

发布要素服务需要已注册数据库解决方法

已发布的接口属性错误和解决方法

系统错误 10053您主机中的软件放弃了一个已建立的连接怎么解决

如何解决“ruby 安装缺少心理”错误?

连接失败 错误为651 已拒绝远程链接