根据列中的唯一值对PySpark数据帧进行分区(自定义分区)

根据列中的唯一值对PySpark数据帧进行分区(自定义分区),pyspark,pyspark-sql,pyspark-dataframes,Pyspark,Pyspark Sql,Pyspark Dataframes,我有一个PySpark数据框,其中有名称、类型、日期和值的单独列。数据帧的示例如下所示: +------+----+---+-----+ | Name|Type|Day|Value| +------+----+---+-----+ | name1| a| 1| 140| | name2| a| 1| 180| | name3| a| 1| 150| | name4| b| 1| 145| | name5| b| 1| 185| | name6| c|

我有一个PySpark数据框,其中有名称、类型、日期和值的单独列。数据帧的示例如下所示:

+------+----+---+-----+
|  Name|Type|Day|Value|
+------+----+---+-----+
| name1|   a|  1|  140|
| name2|   a|  1|  180|
| name3|   a|  1|  150|
| name4|   b|  1|  145|
| name5|   b|  1|  185|
| name6|   c|  1|  155|
| name7|   c|  1|  160|
| name8|   a|  2|  120|
| name9|   a|  2|  110|
|name10|   b|  2|  125|
|name11|   b|  2|  185|
|name12|   c|  3|  195|
+------+----+---+-----+
对于所选的
类型值
,我想根据标题为
Day
的列的唯一值创建单独的数据帧。比如说,我选择了
a
作为我首选的
类型。在上述示例中,我有三个唯一的
Day
(即
1、2、3
)。对于
Day
的每个唯一值,其中有一行具有所选
类型
a
-(即上述数据中的days
1
2
),我想创建一个数据框,其中包含所有具有所选
类型
Day
的行。在上面提到的示例中,我将有两个dataframe,如下所示

+------+----+---+-----+
|  Name|Type|Day|Value|
+------+----+---+-----+
| name1|   a|  1|  140|
| name2|   a|  1|  180|
| name3|   a|  1|  150|
+------+----+---+-----+

我该怎么做?在我将要处理的实际数据中,我有数百万列。因此,我想知道实现上述目标最有效的方法

您可以使用下面提到的代码生成上面给出的示例

from pyspark.sql import *
import numpy as np

Stats = Row("Name", "Type", "Day", "Value")

stat1 = Stats('name1', 'a', 1, 140)
stat2 = Stats('name2', 'a', 1, 180)
stat3 = Stats('name3', 'a', 1, 150)
stat4 = Stats('name4', 'b', 1, 145)
stat5 = Stats('name5', 'b', 1, 185)
stat6 = Stats('name6', 'c', 1, 155)
stat7 = Stats('name7', 'c', 1, 160)
stat8 = Stats('name8', 'a', 2, 120)
stat9 = Stats('name9', 'a', 2, 110)
stat10 = Stats('name10', 'b', 2, 125)
stat11 = Stats('name11', 'b', 2, 185)
stat12 = Stats('name12', 'c', 3, 195)

您只需使用
df.repartition(“Type”,“Day”)

同样的

当我使用下面的函数进行验证时,我得到了上面提到的输出

def validate(partition):
    count = 0
    for row in partition:
        print(row)    
        count += 1
    print(count)
我的数据 在
df.repartition(“user\u id”)
之后,我得到以下信息:

输出
您只需使用
df.repartition(“Type”,“Day”)

同样的

当我使用下面的函数进行验证时,我得到了上面提到的输出

def validate(partition):
    count = 0
    for row in partition:
        print(row)    
        count += 1
    print(count)
我的数据 在
df.repartition(“user\u id”)
之后,我得到以下信息:

输出
我们可以在数据框中看到分区。你是什么意思,@PIG?我的意思是分区发生在数据框中。有没有办法检查一下。df2=df.repartition('day')……伪代码->df2.getpartition().show()不,您看不到分区。您可以看到
df.rdd.getNumPartitions()
,但我认为它会抛出
200
之类的东西。你可以用我写的函数来验证它。@Raghu
df.rdd.foreachPartition(validate)
我们能在数据帧中看到分区吗?你是什么意思,@PIG?我是说分区发生在数据帧内部。有没有办法检查一下。df2=df.repartition('day')……伪代码->df2.getpartition().show()不,您看不到分区。您可以看到
df.rdd.getNumPartitions()
,但我认为它会抛出
200
之类的东西。您可以使用我编写的函数来验证它。@Raghu
df.rdd.foreachPartition(validate)
+------+--------------------+-------+-------+
|amount|          trans_date|user_id|row_num|
+------+--------------------+-------+-------+
|  99.1|2019-06-04T00:00:...|    101|      1|
| 89.27|2019-06-04T00:00:...|    102|      2|
|  89.1|2019-03-04T00:00:...|    102|      3|
| 73.11|2019-09-10T00:00:...|    103|      4|
|-69.81|2019-09-11T00:00:...|    101|      5|
| 12.51|2018-12-14T00:00:...|    101|      6|
| 43.23|2018-09-11T00:00:...|    101|      7|
+------+--------------------+-------+-------+
Row(amount=73.11, trans_date='2019-09-10T00:00:00.000+05:30', user_id='103', row_num=4)
1
Row(amount=89.27, trans_date='2019-06-04T00:00:00.000+05:30', user_id='102', row_num=2)
Row(amount=89.1, trans_date='2019-03-04T00:00:00.000+05:30', user_id='102', row_num=3)
2
Row(amount=99.1, trans_date='2019-06-04T00:00:00.000+05:30', user_id='101', row_num=1)
Row(amount=-69.81, trans_date='2019-09-11T00:00:00.000+05:30', user_id='101', row_num=5)
Row(amount=12.51, trans_date='2018-12-14T00:00:00.000+05:30', user_id='101', row_num=6)
Row(amount=43.23, trans_date='2018-09-11T00:00:00.000+05:30', user_id='101', row_num=7)
4