[英]What is best way to lookup a list of integers in a list of ranged integers in pyspark
我有一個范圍列表,如下所示:
我有一個值列表,如下所示:
現在我需要做的是,對於“值列表”中的每個值,我需要獲取“范圍列表”中行的索引,以便該值介於“從”和“到”之間在“范圍列表”中的那一行。
假設:
用例子解釋上面的,
“值列表”中的第一項是“17”,它落入的范圍將在“范圍列表”的索引 2 處,因為 17 介於 15 和 19 之間。
“值列表”中的第二項是“51”,它落入的范圍將在“范圍列表”的索引 9 處,因為 51 介於 50 和 54 之間。
我想知道是否有任何快速/有效的方法可以在 pyspark 的范圍內進行查找。
對於 Pyspark 1.6+:使用非對等連接來查找匹配范圍。 然后,由於您的行數將比最初的values
多,因為范圍可能重疊,因此按值分組並調用collect_list
。
我添加了一個不在范圍內的值的示例。 如果您不關心它們,請更改數據框與left
連接方式。
ranges = spark.createDataFrame(((1, 0, 5), (2, 4, 7), (3, 8, 10)),
schema=("index", "from", "to"))
values = spark.createDataFrame(((-1,), (3,), (5,), (8,), (100,)),
schema=("value",))
df2 = ranges.join(values,
values.value.between(ranges["from"], ranges["to"]),
how="right") # change to left outliers should be ignored
df2.groupBy("value").agg(collect_list("index").alias("range_indices")).show()
# +-----+-------------+
# |value|range_indices|
# +-----+-------------+
# | 5| [1, 2]|
# | 100| []|
# | 3| [1]|
# | 8| [3]|
# | -1| []|
# +-----+-------------+
這應該適用於 Spark 2.1+:
import pyspark.sql.functions as F
df_ranges = df_ranges.withColumn("id", F.monotonically_increasing_id())
df = df_vals.crossJoin(df_ranges)
df = df.where((F.col('val') >= F.col('from')) & (F.col('value') <= F.col('to')))
df = df.groupby('val').agg(F.collect_set('id').alias('ids'))
df.show()
+------+-----------+
| val| ids|
+------+-----------+
| 17| [2]|
| 51| [9]|
+------+-----------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.