[英]How to drop duplicates from PySpark Dataframe and change the remaining column value to null
[英]PySpark - Extract Max Value for Column for 24 Hour Window, Then Drop Duplicates
我需要為每個id
找到value
的max_value
。 只需要記錄一次最大值,並且在date
當天的第一條記錄處
+---+-------------------+-----+----------+
| id| date|value| date_only|
+---+-------------------+-----+----------+
| J1|2016-10-01 00:00:00| Null|2016-10-01|
| J1|2016-10-01 01:00:00| 1|2016-10-01|
| J1|2016-10-01 12:30:30| 3|2016-10-01|
| J9|2016-10-06 00:00:00| 2|2016-10-06|
| J9|2016-10-06 09:20:00| 4|2016-10-06|
| J9|2016-10-06 09:20:00| Null|2016-10-06|
+---+-------------------+-----+----------+
所需 DataFrame:
+---+-------------------+-----+----------+---------+
| id| date|value| date_only|max_value|
+---+-------------------+-----+----------+---------+
| J1|2016-10-01 00:00:00| Null|2016-10-01| 3|
| J1|2016-10-01 01:00:00| 1|2016-10-01| Null|
| J1|2016-10-01 12:30:30| 3|2016-10-01| Null|
| J9|2016-10-06 00:00:00| 2|2016-10-06| 4|
| J9|2016-10-06 09:20:00| 4|2016-10-06| Null|
| J9|2016-10-06 09:20:00| Null|2016-10-06| Null|
+---+-------------------+-----+----------+---------+
我嘗試了什么:
這只會保留 groupby 變量並從新數據框中排除所有其他變量(100s))
df = df.groupBy("id", "date_only").agg(max("max_value").alias("max_value1")).sort('date_only')
我在下面嘗試過的示例代碼。 每個日期有 96 行,但有時不匹配。 是否有另一個 function 像 pandas DateTime 或者我是否需要刪除 arg 之間的行?
w = Window.partitionBy("ID").orderBy(F.col("date_only").cast('long'))
main = main.withColumn('max_value', F.max("value").over(w))
我也嘗試過,但是它沒有更改列中的重復值:
df.groupBy("ID", "Date").agg(first("max_value").alias("max_value"), count("*").alias("cn")) \
.withColumn("max_value", when(col("cn") > lit(1), lit(None)).otherwise(col("max_value")))
您可以將兩個 WinSpecs 與它們的默認框架一起使用(下面來自doc ):
注意 未定義排序時,默認使用無界 window 幀(rowFrame、unboundedPreceding、unboundedFollowing)。 定義排序時,默認使用增長的 window 框架(rangeFrame、unboundedPreceding、currentRow)。
from pyspark.sql import Window, functions as F
w1 = Window.partitionBy('id')
w2 = Window.partitionBy('id', F.col('date').astype('date')).orderBy('date')
# set up the first records on each day regardless if or not the date is ending with `00:00:00`
df.withColumn('max_value', F.when(F.row_number().over(w2)==1, F.max('value').over(w1))).show()
+---+-------------------+-----+----------+---------+
| id| date|value| date_only|max_value|
+---+-------------------+-----+----------+---------+
| J1|2016-10-01 00:00:00| null|2016-10-01| 3|
| J1|2016-10-01 01:00:00| 1|2016-10-01| null|
| J1|2016-10-01 12:30:30| 3|2016-10-01| null|
| J9|2016-10-06 00:00:00| 2|2016-10-06| 4|
| J9|2016-10-06 09:20:00| 4|2016-10-06| null|
| J9|2016-10-06 09:20:00| null|2016-10-06| null|
+---+-------------------+-----+----------+---------+
編輯:根據評論,將所有以00:00:00
結尾的日期調整為 max_value:
df.withColumn('max_value', F.when(F.col('date') == F.date_trunc('day', 'date'), F.max('value').over(w1))).show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.