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

时间:2019-01-28 12:04:02

标签: apache-spark pyspark apache-spark-sql

案例1::当我尝试获取“ b.no”错误时,下面共享了代码,同时还显示了错误消息。我如何从第二个数据帧中获取值(即别名为b)。这里是否允许从b选择值。如果我删除b.no,则工作正常。

df1.csv 不,姓名,工资 1,斯里兰卡3000 2000年2月 3,山姆,2500 4,kri,5000 5,tom,4000

df2.csv 不,姓名,工资 1,斯里兰卡3000 1,vas,4000 2000年2月 3,山姆,2500 4,kri,5000 5,tom,4500 5,玩具,4200 5,koy,4999 6,吉姆,3090 7,kim,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.sal,a.name] ;; \ n'Project [否#10,名称#11,'b.no] \ n +-AnalysisBarrier \ n +-项目[否#10,名称#11,sal#12,名称#27,sal#28] \ n +-加入内部, (no#10 = no#26)\ n:-SubqueryAlias a \ n:+-Relation [no#10,name#11,sal#12] csv \ n +-SubqueryAlias b \ n +-Relation [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 个答案:

答案 0 :(得分:1)

case1的问题是,当您使用字符串(或数组类型)作为连接参数时,spark只会添加a.no而不是b.no,以避免在连接后出现重复的列(有关更多信息,请参见link信息)。您可以通过定义诸如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| 
+---+----+---+

对于您的Case2:数据框distinct方法比较数据框的每一行。如果只需要一列的唯一值,则必须首先执行选择:

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()