重新分区更改Spark中数据帧的行顺序

时间:2019-11-22 21:59:45

标签: dataframe apache-spark pyspark partition pyspark-dataframes

在我应用.repartition函数后,我想了解数据帧发生了什么。如果我的原始数据框是:

+--------+------+--------------+-------+-----+
|integers|floats|integer_arrays|letters|nulls|
+--------+------+--------------+-------+-----+
|       1|  -1.0|        [1, 2]|      a|    1|
|       2|   0.5|     [3, 4, 5]|      b| null|
|       3|   2.7|  [6, 7, 8, 9]|      c|    2|
+--------+------+--------------+-------+-----+

然后我跑:

df.repartition(10).show()

生成的数据框具有不同顺序的行:

+--------+------+--------------+-------+-----+
|integers|floats|integer_arrays|letters|nulls|
+--------+------+--------------+-------+-----+
|       3|   2.7|  [6, 7, 8, 9]|      c|    2|
|       2|   0.5|     [3, 4, 5]|      b| null|
|       1|  -1.0|        [1, 2]|      a|    1|
+--------+------+--------------+-------+-----+

为什么行顺序会改变?

具有3行并分成10个分区的数据框实际上发生了什么?

我可以看到它分配的分区吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您的初始DataFrame的行分布在不同的分区上。当您调用Scaffold-DbContext "DataSource=D:\Database\SQLite\Example.sqlite" Microsoft.EntityFrameworkCore.Sqlite -OutputDir Model 时,会从分区中获取行的子集并传递给驱动程序,驱动程序将以表格格式显示它们。

要查看将行分配到的分区,请使用pyspark sql函数show

spark_partition_id()

现在,当您要求重新洗牌时,Spark将计算每行的哈希值,并根据该值和洗牌操作中使用的默认分区数,将每行移动到一个(可能不同的)分区,您可以见下文:

>>> from pyspark.sql.functions import spark_partition_id
>>> df0 = spark.range(3)
>>> df1 = df0.withColumn("partition_id_before", spark_partition_id())
>>> df1.show()
+---+-------------------+
| id|partition_id_before|
+---+-------------------+
|  0|                  1|
|  1|                  2|
|  2|                  3|
+---+-------------------+

通常,由于Spark是用于分布式处理的框架,因此我的建议是不要依赖(感知)行的位置顺序,而将DataFrame的内容视为 set (缺少一个集合顺序,就像在小组理论中一样)。像>>> df2 = df1.repartition(10).withColumn("partition_id_after", spark_partition_id()) >>> df2.show() +---+-------------------+------------------+ | id|partition_id_before|partition_id_after| +---+-------------------+------------------+ | 2| 3| 5| | 0| 1| 6| | 1| 2| 9| +---+-------------------+------------------+ 这样的函数通常仅用于显示目的,例如前N个是某物产生的,然后顺序很重要。在大多数操作中,请忽略顺序。

相关问题