[英]alternative of pyspark inner join to compare two dataframes in pyspark
我在 pyspark 中有兩個數據框。 如下所示,df1 包含來自傳感器的整個 long_lat。 第二個 dataframe df2 是第一個 dataframe 的子集,其中 lat-long 值四舍五入到小數點后 2 位,然后刪除重復項以保留唯一的 lat_long 數據點。
df1:
+-----------------+---------+-----+--------------------+----------+------------+
| UID| label|value| datetime| latitude| longitude|
+-----------------+---------+-----+--------------------+----------+------------+
|1B0545GD6546Y|evnt | 3644|2020-06-08T23:32:...|40.1172005|-105.0823546|
|1B0545GD6FG67|evnt | 3644|2020-06-08T23:32:...|40.1172201|-105.0821007|
|15GD6546YFG67|evnt | 3644|2020-06-08T23:32:...|40.1172396|-105.0818468|
|1BGD6546YFG67|evnt | 3644|2020-06-08T23:32:...|40.1172613|-105.0815929|
|1BGD6546YFG67|evnt | 3644|2020-06-08T23:32:...|40.1172808|-105.0813368|
|1B054546YFG67|evnt | 3644|2020-06-08T23:32:...|40.1173003|-105.0810742|
|1B056546YFG67|evnt | 3644|2020-06-08T23:32:...| 40.117322|-105.0808073|
df2:
+-------+--------+----------------+--------------+
|new_lat|new_long| lat_long| State_name|
+-------+--------+----------------+--------------+
| 40.13| -105.1|[40.13, -105.1] | Colorado|
| 40.15| -105.11|[40.15, -105.11]| Colorado|
| 40.12| -105.07|[40.12, -105.07]| Colorado|
| 40.13| -104.99|[40.13, -104.99]| Colorado|
| 40.15| -105.09|[40.15, -105.09]| Colorado|
| 40.15| -105.13|[40.15, -105.13]| Colorado|
| 40.12| -104.94|[40.12, -104.94]| Colorado|
因此,df2 的行數比第一個少得多。 在 df2 中,我應用了一個 udf 來計算 state 名稱。
現在我想在 df1 中填充 state 名稱。 由於 df2 的 lat_long 值被四舍五入到小數點后 2,為了匹配我使用如下閾值,我在這里使用連接操作。
threshold = 0.01
df4 = df1.join(df2)\
.filter(df2.new_lat - threshold < df1.latitude)\
.filter(df1.latitude < df2.new_lat + threshold)
有沒有其他有效的方法來實現同樣的目標? 因為連接操作是做笛卡爾積,它需要時間和大量的任務。
考慮一下,我的 df1 將有 10000 億條記錄。
任何,幫助將不勝感激。
每當您將大 DataFrame 與較小的 DataFrame 連接時,您應該始終嘗試執行廣播連接。
如果df2
小到可以廣播,那么df1.join(broadcast(df2))
的性能會更好。
join()
方法的第二個參數應該是連接條件。
def approx_equal(col1, col2, threshold):
return abs(col1 - col2) < threshold
threshold = lit(0.01)
df4 = df1.join(broadcast(df2), approx_equal(df2.new_lat, df1.latitude, threshold) && approx_equal(df2.new_long, df1. longitude, threshold))
編輯:我將approx_equal
function 添加到quinn ,因此您的代碼可以更簡潔:
import quinn as Q
threshold = lit(0.01)
df4 = df1.join(broadcast(df2), Q.approx_equal(df2.new_lat, df1.latitude, threshold) && Q.approx_equal(df2.new_long, df1. longitude, threshold))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.