我有一個表格,其中包含由uid分組的事件。所有行都有列uid
,visit_num
和event_num
。Spark:根據兩列計數事件
visit_num
是偶爾增加的任意計數器。 event_num
是訪問內相互作用的計數器。
我想將這兩個計數器合併到一個交互計數器中,該計數器對於每個事件不斷增加1,並在下次訪問開始時繼續增加。
正如我只看事件之間的相對距離,如果我不爲1
|uid |visit_num|event_num|interaction_num| | 1 | 1 | 1 | 1 | | 1 | 1 | 2 | 2 | | 1 | 2 | 1 | 3 | | 1 | 2 | 2 | 4 | | 2 | 1 | 1 | 500 | | 2 | 2 | 1 | 501 | | 2 | 2 | 2 | 502 |
啓動計數器它的優良我可以重新分區的數據,並使用monotonically_increasing_id
樣實現這個這樣的:
df.repartition("uid")\
.sort("visit_num", "event_num")\
.withColumn("iid", fn.monotonically_increasing_id())
但是文件指出:
的根erated ID保證單調遞增並且是唯一的,但不是連續的。當前實現將分區ID放在高31位中,並將每個分區中的記錄號放在低33位中。假設數據幀的分區少於10億個,每個分區的記錄少於80億個。
由於ID似乎是通過分區單調增加,這似乎很好。但是:
- 我接近達到10億分區/ uid閾值。
- 我不想依靠目前的實現沒有改變。
有沒有一種方法,我可以啓動每個用1作爲第一個交互數字的數字?
編輯
經過測試該多一些,我注意到,有些用戶似乎並不具備使用上述方法連續iid
值。
編輯2:窗口化
不幸的是有一些(罕見)情況下,超過one row has the same
visit_num and
event_num`。我已經嘗試過使用下面的窗口函數,但是由於這將相同的級別分配給了兩個相同的列,所以這不是一個真正的選擇。
iid_window = Window.partitionBy("uid").orderBy("visit_num", "event_num")
df_sample_iid=df_sample.withColumn("iid", fn.rank().over(iid_window))
您是否考慮過使用窗口集合函數,如rank?這可以在分區內工作,然後您必須在整個數據集上應用「滯後」或相似性。這可以工作(不知道它是如何有效的表現明智)。 –
我已經測試了級別的窗口,它完成了問題中最初概述的工作。不幸的是,我發現它造成了重複行的一些問題,我不希望在數據中看到這些問題。 – Hans
'row_number'呢?你檢查過了嗎? –