[英]pySpark count IDs on condition
我有以下數據集並使用PySpark
df = sparkSession.createDataFrame([(5, 'Samsung', '2018-02-23'),
(8, 'Apple', '2018-02-22'),
(5, 'Sony', '2018-02-21'),
(5, 'Samsung', '2018-02-20'),
(8, 'LG', '2018-02-20')],
['ID', 'Product', 'Date']
)
+---+-------+----------+
| ID|Product| Date|
+---+-------+----------+
| 5|Samsung|2018-02-23|
| 8| Apple|2018-02-22|
| 5| Sony|2018-02-21|
| 5|Samsung|2018-02-20|
| 8| LG|2018-02-20|
+---+-------+----------+
# Each ID will appear ALWAYS at least 2 times (do not consider the case of unique IDs in this df)
每個ID僅在代表較高頻率時才應遞增PRODUCT計數器。 如果頻率相等,則最近的日期應決定哪個產品獲得+1。
從上面的示例中,所需的輸出將是:
+-------+-------+
|Product|Counter|
+-------+-------+
|Samsung| 1|
| Apple| 1|
| Sony| 0|
| LG| 0|
+-------+-------+
# Samsung - 1 (preferred twice by ID=5)
# Apple - 1 (preferred by ID=8 more recently than LG)
# Sony - 0 (because ID=5 preferred Samsung 2 time, and Sony only 1)
# LG - 0 (because ID=8 preferred Apple more recently)
使用PySpark達到此結果的最有效方法是什么?
IIUC,您想為每個ID
選擇最頻繁的商品,並使用最新的Date
打破平局
因此,首先,我們可以使用以下方法獲得每個產品/ ID對的計數:
import pyspark.sql.functions as f
from pyspark.sql import Window
df = df.select(
'ID',
'Product',
'Date',
f.count('Product').over(Window.partitionBy('ID', 'Product')).alias('count')
)
df.show()
#+---+-------+----------+-----+
#| ID|Product| Date|count|
#+---+-------+----------+-----+
#| 5| Sony|2018-02-21| 1|
#| 8| LG|2018-02-20| 1|
#| 8| Apple|2018-02-22| 1|
#| 5|Samsung|2018-02-23| 2|
#| 5|Samsung|2018-02-20| 2|
#+---+-------+----------+-----+
現在,您可以使用Window
對每個ID的每個產品進行排名。 我們可以使用pyspark.sql.functions.desc()
按count
和Date
降序排序。 如果row_number()
等於1,則表示該行是第一行。
w = Window.partitionBy('ID').orderBy(f.desc('count'), f.desc('Date'))
df = df.select(
'Product',
(f.row_number().over(w) == 1).cast("int").alias('Counter')
)
df.show()
#+-------+-------+
#|Product|Counter|
#+-------+-------+
#|Samsung| 1|
#|Samsung| 0|
#| Sony| 0|
#| Apple| 1|
#| LG| 0|
#+-------+-------+
最后對產品進行groupBy()
並為Counter
選擇最大值:
df.groupBy('Product').agg(f.max('Counter').alias('Counter')).show()
#+-------+-------+
#|Product|Counter|
#+-------+-------+
#| Sony| 0|
#|Samsung| 1|
#| LG| 0|
#| Apple| 1|
#+-------+-------+
更新資料
這是一個簡單的方法:
w = Window.partitionBy('ID').orderBy(f.desc('count'), f.desc('Date'))
df.groupBy('ID', 'Product')\
.agg(f.max('Date').alias('Date'), f.count('Product').alias('Count'))\
.select('Product', (f.row_number().over(w) == 1).cast("int").alias('Counter'))\
.show()
#+-------+-------+
#|Product|Counter|
#+-------+-------+
#|Samsung| 1|
#| Sony| 0|
#| Apple| 1|
#| LG| 0|
#+-------+-------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.