Apache spark 错误:联接中缺少已解析的属性

Apache spark 错误:联接中缺少已解析的属性,apache-spark,pyspark,Apache Spark,Pyspark,我使用pyspark对具有相对复杂连接条件的两个表执行连接(在连接条件中使用大于/小于)。这可以正常工作,但只要在连接之前添加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

我使用pyspark对具有相对复杂连接条件的两个表执行
连接
(在连接条件中使用大于/小于)。这可以正常工作,但只要在连接之前添加
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')
)
这会导致如下错误:

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#4765缺少解析属性,col2#4766,col3#4768,colx#4823,coly#4830,colz#4764!加入LeftOuter(((col1#4765=colx#4823)和&(col2#4766=coly#4830)和&(col3#4768>=colz#4764))。具有相同名称的属性出现在操作中:col1。请检查是否使用了正确的属性

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

我已经看过了,但这些答案对我来说并不适用。具体来说,在
填充后使用
.alias('a')
无效,因为then spark无法识别连接条件中的
a

谁能:

  • 请确切解释为什么会发生这种情况,以及我今后如何避免这种情况
  • 你能给我一个解决方法的建议吗
提前感谢您的帮助。

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

查看此效果的一种方法是在替换空值之前和之后调用dataframe:

df_a.explain()
印刷品

==物理计划==
*(1) 项目[#1#0L为col1#6L、#2#1L为col2#7L、#3#2L为col3#8L]
+-*(1)扫描现有RDD[_1#0L、_2#1L、_3#2L]

df_a.fillna(42,子集=['col1']).explain()
印刷品

==物理计划==
*(1) 项目[合并(_1#0L,42)为col1#27L,_2#1L为col2#7L,_3#2L为col3#8L]
+-*(1)扫描现有RDD[_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',子集=['col1']))
加入条件=[
df_a.col1==df_b.colx,
[...]
如果不可能或需要,您可以更改联接条件。您可以使用与任何数据帧不关联的列,而不是使用数据帧(
df_a.col1
)中的列。此列仅根据其名称工作,因此在数据帧中替换该列时忽略:

从pyspark.sql导入函数为F
加入条件=[
F.col(“col1”)==df_b.colx,
df_a.col2==df_b.coly,
df_a.col3>=df_b.colz
]

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

有太多修改过的列,无法理解。回答得太好了!谢谢。这澄清了很多隐藏的内容。