Apache spark 火花管接头柱顺序

Apache spark 火花管接头柱顺序,apache-spark,pyspark,apache-spark-sql,pyspark-sql,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Sql,我最近在Spark遇到了一些奇怪的事情。据我所知,考虑到spark dfs基于列的存储方法,列的顺序实际上没有任何意义,它们就像字典中的键 在df.union(df2)期间,列的顺序是否重要?我本以为它不应该这样做,但根据sql论坛的智慧,它确实应该这样做 因此,我们有df1 df1 | a| b| +---+----+ | 1| asd| | 2|asda| | 3| f1f| +---+----+ df2 | b| a| +----+---+ | asd| 1| |as

我最近在Spark遇到了一些奇怪的事情。据我所知,考虑到spark dfs基于列的存储方法,列的顺序实际上没有任何意义,它们就像字典中的键

df.union(df2)
期间,列的顺序是否重要?我本以为它不应该这样做,但根据sql论坛的智慧,它确实应该这样做

因此,我们有
df1

df1
|  a|   b|
+---+----+
|  1| asd|
|  2|asda|
|  3| f1f|
+---+----+

df2
|   b|  a|
+----+---+
| asd|  1|
|asda|  2|
| f1f|  3|
+----+---+

result
|   a|   b|
+----+----+
|   1| asd|
|   2|asda|
|   3| f1f|
| asd|   1|
|asda|   2|
| f1f|   3|
+----+----+

看起来使用了来自df1的模式,但数据似乎按照其原始数据帧的顺序连接。 显然,解决方案是执行
df1.union(df2.select(df1.columns))

但主要问题是,它为什么会这样做?这仅仅是因为它是pyspark.sql的一部分,还是因为我在理解Spark时弄错了它的底层数据架构

如果有人想尝试,请编写代码来创建测试集

d1={'a':[1,2,3], 'b':['asd','asda','f1f']}
d2={ 'b':['asd','asda','f1f'], 'a':[1,2,3],}
pdf1=pd.DataFrame(d1)
pdf2=pd.DataFrame(d2)
df1=spark.createDataFrame(pdf1)
df2=spark.createDataFrame(pdf2)
test=df1.union(df2)

在spark Union中,并没有对列的元数据进行处理,数据也并没有像你们想象的那个样被洗牌。相反,联合是在列编号上进行的,如中所示,如果联合2个Df,则两者必须具有相同的列编号。在进行联合之前,必须考虑列的位置。与SQL、Oracle或其他RDBMS不同,spark中的底层文件是物理文件。希望回答您的问题

Spark union是根据标准SQL实现的,因此可以按位置解析列。API也说明了这一点:

返回一个新的数据帧,其中包含此帧和另一帧中的行的并集

这相当于SQL中的UNION ALL。要执行SQL样式集联合(即>元素重复数据消除),请使用此函数,然后使用一个独特的

该函数也是SQL中的标准函数,它按位置(而不是名称)解析列


因为Spark>=2.3如果列名得到解析,您可以使用合并两个数据帧。

明白了,这很有意义。这是使用列顺序的唯一操作吗?还是有其他情况?我只是假设联合像连接一样工作,并且数据被随意移动,我猜这解释了为什么联合相对来说比较快,我没有处理太多的列排序tbh。但是联合是我能想到的一种情况。使用
unionByName
union
相比,会对性能产生影响吗?当然,因为spark以前需要检查现有的列名,但它是一个小的列名()。而且,unionByName显然与unionAll类似,因为它不会重复记录。@组合学家,这是正确的。您必须先使用它,然后再使用它来消除行中的重复数据。