【问题标题】:Spark union column orderSpark union 列顺序
【发布时间】:2019-11-18 09:21:44
【问题描述】:

我最近在 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)

【问题讨论】:

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


    【解决方案1】:

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

    返回一个新的 DataFrame,其中包含此帧和另一个帧中的行的联合。

    这相当于 SQL 中的 UNION ALL。要执行 SQL 样式的集合并集(对元素进行>重复数据删除),请使用此函数,后跟一个 distinct。

    同样作为 SQL 中的标准,此函数按位置(而不是按名称)解析列。

    由于 Spark >= 2.3,您可以使用 unionByName 来合并两个数据帧(如果列名得到解析)。

    【讨论】:

    • 使用unionByNameunion 对性能有影响吗?
    • 当然因为spark之前需要检查现有的列名,但它很小(link)。
    • 此外,unionByName 显然与 unionAll 相似,因为它不会重复记录。
    • @combinatorist 没错。您必须使用它后跟.distinct() 来删除重复行。
    【解决方案2】:

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

    【讨论】:

    • 明白了,这是有道理的。这是唯一使用列顺序的操作吗?还是有其他情况?我只是假设工会像联接一样工作,数据会被打乱,猜想它解释了为什么工会相对较快
    • 我不必处理太多的列排序问题。但工会是我能想到的一种情况。
    猜你喜欢
    • 2017-05-07
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多