Python 在pyspark中查找范围整数列表中的整数列表的最佳方法是什么

Python 在pyspark中查找范围整数列表中的整数列表的最佳方法是什么,python,pyspark,databricks,Python,Pyspark,Databricks,我有一个范围列表,如下所示: 我有一个值列表,如下所示: 现在我需要做的是,对于“值列表”中的每个值,我需要获得“范围列表”中该行的索引,这样该值就位于“范围列表”中该行的“From”和“to”之间 假设: 这两个列表都是数据帧(我更愿意使用pyspark) “范围列表”中可能存在重叠,在这种情况下,返回所有可能的范围索引 “从”和“到”值是包含的 “范围列表”可以有超过1亿行 “值列表”的长度将始终小于“范围列表”。(即使我的照片没有显示) 举例说明上述情况 “值列表”中的第一项是“1

我有一个范围列表,如下所示:

我有一个值列表,如下所示:

现在我需要做的是,对于“值列表”中的每个值,我需要获得“范围列表”中该行的索引,这样该值就位于“范围列表”中该行的“From”和“to”之间

假设:

  • 这两个列表都是数据帧(我更愿意使用pyspark)
  • “范围列表”中可能存在重叠,在这种情况下,返回所有可能的范围索引
  • “从”和“到”值是包含的
  • “范围列表”可以有超过1亿行
  • “值列表”的长度将始终小于“范围列表”。(即使我的照片没有显示)
举例说明上述情况

“值列表”中的第一项是“17”,其范围将位于“范围列表”的索引2处,因为17介于15和19之间

“值列表”中的第二项为“51”,其范围将位于“范围列表”的索引9处,因为51介于50和54之间


我想知道是否有任何快速/有效的方法可以在pyspark中查找范围。

这应该适用于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]|
        +------+-----------+
导入pyspark.sql.F函数
df_ranges=df_ranges.withColumn(“id”,F.单调地增加_id())
df=df值交叉连接(df值范围)

df=df。其中((F.col('val')>=F.col('from'))和(F.col('value'))这应该适用于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]|
        +------+-----------+
导入pyspark.sql.F函数
df_ranges=df_ranges.withColumn(“id”,F.单调地增加_id())
df=df值交叉连接(df值范围)

df=df。其中((F.col('val')>=F.col('from'))和(F.col('value'))对于Pyspark 1.6+:使用非等联接查找匹配的范围。然后,由于范围可能重叠,因此您将有比
最初更多的行,请按值分组并调用
收集列表

我添加了一个不在范围内的值示例。如果您不关心这些值,请将数据帧的连接方式更改为
left

ranges=spark.createDataFrame(((1,0,5)、(2,4,7)、(3,8,10)),
模式=(“索引”、“从”、“到”))
值=spark.createDataFrame((-1,),(3,),(5,),(8,),(100,),
模式=(“值”,))
df2=范围。连接(值,
values.value.between(范围[“从”]、范围[“到”]),
how=“right”)#应忽略对左侧异常值的更改
df2.groupBy(“value”).agg(collect_list(“index”).alias(“range_index”).show()
# +-----+-------------+
#|值|范围|指数|
# +-----+-------------+
# |    5|       [1, 2]|
# |  100|           []|
# |    3|          [1]|
# |    8|          [3]|
# |   -1|           []|
# +-----+-------------+

对于Pyspark 1.6+:使用非等联接查找匹配的范围。然后,由于您的行数将多于
最初的行数,因为这些范围可能重叠,请按值分组并调用
收集列表

我添加了一个不在范围内的值示例。如果您不关心这些值,请将数据帧的连接方式更改为
left

ranges=spark.createDataFrame(((1,0,5)、(2,4,7)、(3,8,10)),
模式=(“索引”、“从”、“到”))
值=spark.createDataFrame((-1,),(3,),(5,),(8,),(100,),
模式=(“值”,))
df2=范围。连接(值,
values.value.between(范围[“从”]、范围[“到”]),
how=“right”)#应忽略对左侧异常值的更改
df2.groupBy(“value”).agg(collect_list(“index”).alias(“range_index”).show()
# +-----+-------------+
#|值|范围|指数|
# +-----+-------------+
# |    5|       [1, 2]|
# |  100|           []|
# |    3|          [1]|
# |    8|          [3]|
# |   -1|           []|
# +-----+-------------+

索引实际上是数据帧中的一些ID列吗?或者您想要行号?实际上我想要行号。更具体地说,我应该能够从所属范围的相同行号中获取其他列的值。请给出一个输出示例,那么索引实际上是数据帧中的一些ID列吗?或者你想要行号?实际上我想要行号。更具体地说,我应该能够从所属范围的相同行号中获取其他列的值(如果存在)。请给出一个输出示例,这不是操作“df.where((F.col('val')>=F.col('from'))&(F.col('value'))您必须扫描整个表,因为答案可能是值的大小乘以我在对每行应用udf时考虑的范围,并使spark以最有效的方式处理它。解决方案中突出显示的操作也会以同样的方式工作吗?udf很慢,但即使如此,在任何解决方案中,您也不能避免所有值和范围之间的交叉,因为答案可能包括所有值和范围。此操作不是“df.where((F.col('val')>=F.col('from'))&(F.col('value'))您必须扫描整个表,因为答案可能是值的大小乘以我在对每行应用udf时考虑的范围,并使spark以最有效的方式处理它。解决方案中突出显示的操作也会以同样的方式工作吗?udf很慢,但即使如此,在任何解决方案中,您也不能ot避免所有值和范围之间的交叉,因为答案可能包括所有值和范围。我的范围dataframe length=11864603,值dataframe length=504719。连接在大约0.04秒内完成,但当我尝试进行显示时,操作因异常而中止org.apache.spark.SparkException:在Future.get中抛出异常:“@Sen,是的,这不是问题。我只给出了一个s