【问题标题】:How to group data based on multiple columns and construct a new column - Pyspark如何根据多列对数据进行分组并构造一个新列 - Pyspark
【发布时间】:2021-10-19 12:17:47
【问题描述】:

我正在学习 Pyspark,我用它来将 csv 文件读入数据框(带有列名):

>>> example_df.show(n=5)
+---------------------+------+-------------+---------+---------+-------------+------------+
|                   id| price|       street| locality|town_city|     district|     country|
+---------------------+------+-------------+---------+---------+-------------+------------+
|                bbbb1|295000|   HAYES YARD|   INGHAM|  LINCOLN| WEST LINDSEY|LINCOLNSHIRE|
|                aaaa2|450000|   MARKET WAY|PINCHBECK| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|
|                bbbb2|280000|   HAYES YARD|   INGHAM|  LINCOLN| WEST LINDSEY|LINCOLNSHIRE|
|                aaaa3|425000|   MARKET WAY|PINCHBECK| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|
|                cccc1| 96000|CHANCERY LANE| HOLBEACH| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|
+---------------------+------+-------------+---------+---------+-------------+------------+
only showing top 5 rows

对于相同的位置(=street|locality|town_city|district|country 的相同值),我想创建一个新的location_id,并将相应的字段分组,如下所示:

+-----------+---------------------+------+-------------+---------+---------+-------------+------------+
|location_id|                   id| price|       street| locality|town_city|     district|     country|
+-----------+---------------------+------+-------------+---------+---------+-------------+------------+
|          0|                aaaa2|450000|   MARKET WAY|PINCHBECK| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|
|          0|                aaaa3|425000|   MARKET WAY|PINCHBECK| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|
|          1|                bbbb1|295000|   HAYES YARD|   INGHAM|  LINCOLN| WEST LINDSEY|LINCOLNSHIRE|
|          1|                bbbb2|280000|   HAYES YARD|   INGHAM|  LINCOLN| WEST LINDSEY|LINCOLNSHIRE|
|          2|                cccc1| 96000|CHANCERY LANE| HOLBEACH| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|
+-----------+---------------------+------+-------------+---------+---------+-------------+------------+
only showing top 5 rows
...

我知道如何创建新列:

from pyspark.sql.functions import monotonically_increasing_id
df = df.WithColumn("location_id", monotonically_increasing_id())

这只是使用0,1,2 etc 创建一个新列,但是我如何将同一位置的数据分组并赋予它们唯一的location_id?谢谢。

【问题讨论】:

    标签: python apache-spark pyspark group-by apache-spark-sql


    【解决方案1】:

    如果您只需要每个位置的 id,您可以使用 hash

    from pyspark.sql import functions as F
    
    example_df.withColumn('location_id', 
        F.hash('street','locality','town_city','district','country')) \
        .show()
    

    输出:

    +-----+------+-------------+---------+---------+-------------+------------+-----------+
    |   id| price|       street| locality|town_city|     district|     country|location_id|
    +-----+------+-------------+---------+---------+-------------+------------+-----------+
    |bbbb1|295000|   HAYES YARD|   INGHAM|  LINCOLN| WEST LINDSEY|LINCOLNSHIRE|  406601501|
    |aaaa2|450000|   MARKET WAY|PINCHBECK| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|  -97363104|
    |bbbb2|280000|   HAYES YARD|   INGHAM|  LINCOLN| WEST LINDSEY|LINCOLNSHIRE|  406601501|
    |aaaa3|425000|   MARKET WAY|PINCHBECK| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE|  -97363104|
    |cccc1| 96000|CHANCERY LANE| HOLBEACH| SPALDING|SOUTH HOLLAND|LINCOLNSHIRE| 1396052469|
    +-----+------+-------------+---------+---------+-------------+------------+-----------+
    

    编辑:请记住hash 函数可能会导致hash collisions

    【讨论】:

    • 谢谢,请问为什么有些哈希值是负数?有没有办法将location_id 移动到第一列?
    • @Cecilia hash 函数可能会返回负值和正值。它不是一个 id 生成器(可能会导致hash collisions,尽管如果数据集不太大,这种可能性不大)。要仅生成正值,请查看this answer。要重新排序列,您可以使用.select('location_id', 'id', 'price', ...)
    • 谢谢,您提到的将哈希转换为正值的答案是在 Scala 中,只是想知道如何在 Python 中实现它?
    • 看来我们也可以使用F.sha2: ://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.functions.sha2.html 但是它似乎不需要多列,我尝试了example_df.withColumn('location_id', F.sha2('street','locality','town_city','district','country')),但它给了我错误TypeError: sha2() takes 2 positional arguments but 5 were given
    猜你喜欢
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2020-08-05
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多