Spark union 列顺序
Spark union column order
我最近在 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 联合是根据标准 SQL 实现的,因此按位置解析列。 API documentation:
也说明了这一点
Return a new DataFrame containing union of rows in this and another frame.
This is equivalent to UNION ALL in SQL. To do a SQL-style set union (that does >deduplication of elements), use this function followed by a distinct.
Also as standard in SQL, this function resolves columns by position (not by name).
因为 Spark >= 2.3 你可以使用 unionByName 联合两个数据帧,列名得到解析。
我最近在 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 联合是根据标准 SQL 实现的,因此按位置解析列。 API documentation:
也说明了这一点Return a new DataFrame containing union of rows in this and another frame.
This is equivalent to UNION ALL in SQL. To do a SQL-style set union (that does >deduplication of elements), use this function followed by a distinct.
Also as standard in SQL, this function resolves columns by position (not by name).
因为 Spark >= 2.3 你可以使用 unionByName 联合两个数据帧,列名得到解析。