Apache spark org.apache.spark.sql.AnalysisException:无法解析

Apache spark org.apache.spark.sql.AnalysisException:无法解析,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,案例1:当我试图获取“b.no”获取错误时,下面将共享代码和错误消息。如何从第二个数据帧(即别名为b)获取值。此处是否允许从b中选择值。如果我删除b.no,它工作正常 df1.csv 不,姓名,萨尔 1,斯里兰卡,3000 2000年12月2日,拉姆 山姆,2500 4,克里夫,5000 汤姆,4000 df2.csv 不,姓名,萨尔 1,斯里兰卡,3000 1,vas,4000 2000年12月2日,拉姆 山姆,2500 4,克里夫,5000 汤姆,4500 5,玩具,4200 5,koy,4

案例1:当我试图获取“b.no”获取错误时,下面将共享代码和错误消息。如何从第二个数据帧(即别名为b)获取值。此处是否允许从b中选择值。如果我删除b.no,它工作正常

df1.csv 不,姓名,萨尔 1,斯里兰卡,3000 2000年12月2日,拉姆 山姆,2500 4,克里夫,5000 汤姆,4000

df2.csv 不,姓名,萨尔 1,斯里兰卡,3000 1,vas,4000 2000年12月2日,拉姆 山姆,2500 4,克里夫,5000 汤姆,4500 5,玩具,4200 5,koy,4999 吉姆,3090 金姆,2080

代码:

from pyspark.shell import spark
from pyspark.sql import SQLContext

sc = spark.sparkContext
sqlContext = SQLContext(sc)

df11 = spark.read.option("header","true").option("delimiter", ",").csv("C:\\inputs\\df1.csv")
df22 = spark.read.option("header","true").option("delimiter", ",").csv("C:\\inputs\\df2.csv")
print("df11", df11.count())
print("df22", df22.count())

resDF = df11.alias("a").join(df22.alias("b"), on='no').select("a.no", "a.name", "b.no")
print("resDF", resDF.count())
print("resDF", resDF.distinct().show())
错误:

py4j.protocol.Py4JJavaError:调用o48.select时出错。 :org.apache.spark.sql.AnalysisException:无法解析给定输入列“
b.no
”[b.sal,a.no,b.name,a.sal,a.name];; pyspark.sql.utils.AnalysisException:“无法解析给定输入列“
b.no
”[b.sal,a.no,b.name,a.name];\n'Project[no#10,name#11,'b.no]\n+-AnalysisBarrier\n+-Project[no#10,name#11,sal#12,name#27,sal#28]\n+-Join-internal no#10=subquerias]:-26:-a:-n:-[no#10,name#11,sal#12]csv\n+-子查询列表b\n+-关系[no#26,name#27,sal#28]csv\n”

案例2:当我使用b.sal获取重复值时,它不会过滤掉

    resDF = df11.alias("a").join(df22.alias("b"), on='no').select("a.no", "a.name", "b.sal")      
print("resDF", resDF.distinct().show())

在本例中,如何仅基于“no”获取不同的值。

案例1中的问题是,当您使用字符串(或arraytype)作为连接参数时,spark将只添加a.no而不是b.no,以避免连接后出现重复列(有关详细信息,请参阅)。您可以通过定义类似于F.col('a.no')==col('b.no')的连接表达式来避免这种情况。请参阅下面的完整示例:

from pyspark.sql import types as T
from pyspark.sql import functions as F
columns1 = ['no','name','sal']
columns2 = ['no','name','sal']

vals1 = [(1,'sri',3000) ,(2,'ram',2000) ,(3,'sam',2500) ,(4,'kri',5000) ,(5,'tom',4000)]

vals2 = [(1,'sri',3000) ,(1,'vas',4000) ,(2,'ram',2000) ,(3,'sam',2500), (4,'kri',5000) ,(5,'tom',4500) ,(5,'toy',4200) ,(5,'koy',4999) ,(6,'jim',3090) ,(7,'kim',2080)]

df1 = spark.createDataFrame(vals1, columns1)
df2 = spark.createDataFrame(vals2, columns2)
#here I use a expression instead of a string
resDF = df1.alias("a").join(df2.alias("b"), F.col('a.no') == col('b.no')).select("a.no", "a.name", "b.no")
resDF.show()
输出:

+---+----+---+ 
| no|name| no| 
+---+----+---+ 
|  0|   1|  0| 
+---+----+---+
对于您的案例2:dataframe方法比较dataframe的每一行。当您只需要一列的唯一值时,必须首先执行select:

resDF = df1.alias("a").join(df2.alias("b"), F.col('a.no') == col('b.no')).select("a.no", "a.name", "b.sal")      
resDF.select('no').distinct().show()

你能补充一些关于df1结构的细节吗?你的问题写得不好。请把df1和df2的表放在一起。第一行是列,其他行是数据,所以数据帧df11和df22只有3列(否,名称,sal)每个?我都更新了我的答案。关于使用F.col和on='on'的最后一个问题给出了相同的结果。我不完全理解这里的区别。如果我想在下面的条件下测试不相等,如何修改条件。F.col('a.no')==col('b.no')))谢谢您的时间。不,不,联接表达式不会给出与联接语句相同的字符串结果。在列“No”上使用联接表达式生成的数据帧将只有一个“No”列(在您的情况下为a.No)。当您将字符串用作联接语句时,生成的数据帧将有两个“No”列(你的情况是a.no和b.no)。试一试:
df1.alias(“a”).join(df2.alias(“b”)、F.col('a.no')==col('b.no')).printSchema()
df1.alias(“a”).join(df2.alias(“b”),on='no').printSchema()
这很好,现在澄清了。非常感谢。:-)