【问题标题】:Pyspark groupBy and consolidatng on multiple distinct column valuesPyspark groupBy 和 consolidatng 在多个不同的列值上
【发布时间】:2020-08-11 08:52:15
【问题描述】:

尝试为 A 列和 B 列的不同值提取具有最新日期的记录(如下)

理想结果:

当前解决方案:

from pyspark.sql import functions as f
test = df.groupBy(df['A'], df['B']).agg(f.first(df['C']), f.first(df['D']), f.max(df['E']))

有什么漏洞可以寻找或优化以上的建议吗?

【问题讨论】:

  • 是熊猫的df吗?试试这个:test = df.groupBy(["A", "B"]).agg(cFirst=("C", "first"), dFirst=("C", "first"), cFirst=("C", "max")) 不完全确定你是否也在 pyspark 中加载了 df..

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


【解决方案1】:

date 列上使用 Window 函数和 max 并将其用于 filter强>。

from pyspark.sql import functions as F
from pyspark.sql.window import Window


w=Window().partitionBy("A","B")

df1.withColumn("max", F.max(F.to_date("E","yyyyMMdd")).over(w))\
  .filter(F.to_date(F.col("E"),"yyyyMMdd")==F.col("max")).drop("max").show()

如果 E(date) 列是 not of StringType,请使用:

w=Window().partitionBy("A","B")

df.withColumn("max", F.max(F.to_date(F.col("E").cast('string'),"yyyyMMdd")).over(w))\
  .filter(F.to_date(F.col("E").cast('string'),"yyyyMMdd")==F.col("max")).drop("max").show()

输出:

#+---+---+----+---+--------+
#|  A|  B|   C|  D|       E|
#+---+---+----+---+--------+
#| 12|ERP|7500|  D|20200330|
#| 12|ERF|4500|  D|20200430|
#+---+---+----+---+--------+

【讨论】:

    【解决方案2】:

    您可以对E列进行降序排序,然后使用row_number函数仅提取最新数据。

    df.show()
    #+---+---+----+---+--------+
    #|  A|  B|   C|  D|       E|
    #+---+---+----+---+--------+
    #| 12|ERP|1000|  M|20200130|
    #| 12|ERP|2000|  M|20200228|
    #| 12|ERP|7500|  D|20200330|
    #| 12|ERF|4500|  D|20200430|
    #| 12|ERF|4000|  L|20200228|
    #| 12|ERF|3400|  L|20200330|
    #+---+---+----+---+--------+
    from pyspark.sql.functions import *
    from pyspark.sql import *
    
    w=Window.partitionBy("A","B").orderBy(col("Z").desc())
    
    df.withColumn("z",to_date(col("E"),"yyyyMMdd")).\
    withColumn("rn",row_number().over(w)).\
    filter(col("rn") == 1).\
    drop(*['z','rn']).\
    show()
    #+---+---+----+---+--------+
    #|  A|  B|   C|  D|       E|
    #+---+---+----+---+--------+
    #| 12|ERP|7500|  D|20200330|
    #| 12|ERF|4500|  D|20200430|
    #+---+---+----+---+--------+
    

    【讨论】:

    • 这行得通,部分比我的解决方案快。虽然我在取最大值之前没有将字符串日期转换为日期格式。
    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 2020-10-09
    • 2021-08-28
    • 1970-01-01
    • 2018-10-14
    • 2018-12-31
    • 1970-01-01
    • 2018-07-02
    相关资源
    最近更新 更多