为什么在 pyspark 中联接两个临时视图后删除列不起作用,但适用于数据框联接?



我需要从数据帧中创建tempView,然后我需要连接这些tempview并删除重复的列。所以我写了下面提到的代码:

Data1 = [  ("xx1",34,60),
("xx2",33,80),
("xx3",37,50) ]
dataSchema1 = StructType([
StructField("Name",StringType(),True),
StructField("Age",IntegerType(),True),
StructField("Id",IntegerType(),True)
])
Data2 = [  (60,"M",3000.60),
(80,"F",3300.80),
(50,"M",5000.50) ]
dataSchema2 = StructType([
StructField("Id",IntegerType(),True),
StructField("Gender", StringType(), True),
StructField("Salary", DoubleType(), True)
])
df1 = spark.createDataFrame(spark.sparkContext.parallelize(Data1),schema=dataSchema1)
df1.createOrReplaceTempView('view1')
df2 = spark.createDataFrame(spark.sparkContext.parallelize(Data2),schema=dataSchema2)
df2.createOrReplaceTempView('view2')
jDF=spark.sql("select * from view1 join view2 on view1.Id = view2.Id")
jDF.columns                 // ['Name', 'Age', 'Id', 'Id', 'Gender', 'Salary']
rjDF=jDF.drop('view2.ID')    //this function is not working
rjDF.columns                // ['Name', 'Age', 'Id', 'Id', 'Gender', 'Salary']

在上面的代码中,drop列方法没有按预期工作,也没有抛出任何错误。然而,若我尝试使用数据帧来删除列(在我的用例中,这显然不是一个更好的选择(,那个么删除方法可以很好地工作。

joinDF=df1.join(df2, df1.Id == df2.Id)
dropped=joinDF.drop(df2.Id)    // working absolutely fine
dropped.columns               // ['Name', 'Age', 'Id', 'Gender', 'Salary']

有人能帮助我理解从联接的临时视图中删除列的第一种方法有什么问题吗?

drop从数据集中删除column namescolumn本身。如果架构不包含column name(s),则这是no-op操作。

drop内部使用analyzer.resolver来检查所提供的字符串是否存在于数据帧中请注意,您无法提供在drop中引用列的类似sql的语法如果您提供相同的spark,则会将整个字符串作为列名。

selectExpr("..")functions.expr("..")内部使用sessionState.sqlParser来解析引用列(如<table/view name>.<column_name>(的类似sql的语法。

如果你想使用类似sql的语法-,请尝试使用expr函数

rjDF=jDF.drop(F.expr('view2.Id'))

否则你可以使用基于drop-的工作列

dropped=joinDF.drop(df2.Id)

最新更新