Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在Spark中检查组的开始、中间和结束_Apache Spark_Apache Spark Sql_Window Functions - Fatal编程技术网

Apache spark 在Spark中检查组的开始、中间和结束

Apache spark 在Spark中检查组的开始、中间和结束,apache-spark,apache-spark-sql,window-functions,Apache Spark,Apache Spark Sql,Window Functions,我有一个Spark数据框,看起来像这样: +---+-----------+-------------------------+---------------+ | id| Phase | Switch | InputFileName | +---+-----------+-------------------------+---------------+ | 1| 2| 1|

我有一个Spark数据框,看起来像这样:

+---+-----------+-------------------------+---------------+
| id| Phase     | Switch                  | InputFileName |
+---+-----------+-------------------------+---------------+
|  1|          2|                        1|          fileA|
|  2|          2|                        1|          fileA|
|  3|          2|                        1|          fileA|
|  4|          2|                        0|          fileA|
|  5|          2|                        0|          fileA|
|  6|          2|                        1|          fileA|
| 11|          2|                        1|          fileB|
| 12|          2|                        1|          fileB|
| 13|          2|                        0|          fileB|
| 14|          2|                        0|          fileB|
| 15|          2|                        1|          fileB|
| 16|          2|                        1|          fileB|
| 21|          4|                        1|          fileB|
| 22|          4|                        1|          fileB|
| 23|          4|                        1|          fileB|
| 24|          4|                        1|          fileB|
| 25|          4|                        1|          fileB|
| 26|          4|                        0|          fileB|
| 31|          1|                        0|          fileC|
| 32|          1|                        0|          fileC|
| 33|          1|                        0|          fileC|
| 34|          1|                        0|          fileC|
| 35|          1|                        0|          fileC|
| 36|          1|                        0|          fileC|
+---+-----------+-------------------------+---------------+
对于每个组(包括
InputFileName
Phase
),我需要运行一个验证函数,检查
Switch
在组的开始和结束处是否等于1,并在这两者之间的任意点转换为0。函数应将验证结果添加为新列。预期结果如下:(差距只是为了突出不同的群体)

我以前使用Pyspark和熊猫UDF解决了这个问题:

df = df.groupBy("InputFileName", "Phase").apply(validate_profile)

@pandas_udf(schema, PandasUDFType.GROUPED_MAP)
def validate_profile(df: pd.DataFrame):
    first_valid = True if df["Switch"].iloc[0] == 1 else False
    during_valid = (df["Switch"].iloc[1:-1] == 0).any()
    last_valid = True if df["Switch"].iloc[-1] == 1 else False
    df["Valid"] = first_valid & during_valid & last_valid
    return df
但是,现在我需要在Scala中重写它。我只是想知道实现这一目标的最佳方式

我目前正在尝试使用窗口函数获取每个组的第一个和最后一个ID:

val minIdWindow = Window.partitionBy("InputFileName", "Phase").orderBy("id")
val maxIdWindow = Window.partitionBy("InputFileName", "Phase").orderBy(col("id").desc)
然后,我可以将最小ID和最大ID添加为单独的列,并在
时使用
来获取
开关的起始值和结束值

df.withColumn("MinId", min("id").over(minIdWindow))
    .withColumn("MaxId", max("id").over(maxIdWindow))
    .withColumn("Valid", when(
        col("id") === col("MinId"), col("Switch")
    ).when(
        col("id") === col("MaxId"), col("Switch")
    ))
这会得到起始值和结束值,但我不确定如何检查
开关
之间是否等于0。使用窗口功能是否正确?或者你会推荐一个替代方案吗?

试试这个

val wind = Window.partitionBy("InputFileName", "Phase").orderBy("id")
  .rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)

val df1 = df.withColumn("Valid", 
  when(first("Switch").over(wind) === 1 
    && last("Switch").over(wind) === 1 
    && min("Switch").over(wind) === 0, true)
    .otherwise(false))
df1.orderBy("id").show() //Ordering for display purpose
输出:

+---+-----+------+-------------+-----+
| id|Phase|Switch|InputFileName|Valid|
+---+-----+------+-------------+-----+
|  1|    2|     1|        fileA| true|
|  2|    2|     1|        fileA| true|
|  3|    2|     1|        fileA| true|
|  4|    2|     0|        fileA| true|
|  5|    2|     0|        fileA| true|
|  6|    2|     1|        fileA| true|
| 11|    2|     1|        fileB| true|
| 12|    2|     1|        fileB| true|
| 13|    2|     0|        fileB| true|
| 14|    2|     0|        fileB| true|
| 15|    2|     1|        fileB| true|
| 16|    2|     1|        fileB| true|
| 21|    4|     1|        fileB|false|
| 22|    4|     1|        fileB|false|
| 23|    4|     1|        fileB|false|
| 24|    4|     1|        fileB|false|
| 25|    4|     1|        fileB|false|
| 26|    4|     0|        fileB|false|
| 31|    1|     0|        fileC|false|
| 32|    1|     0|        fileC|false|
+---+-----+------+-------------+-----+

谢谢@Sathiyan S,已经完成了。它验证了我使用windows函数的方法。无界窗口也是一个关键信息。在阅读之后,我现在看到它考虑了整个窗口,而不仅仅是当前行。
+---+-----+------+-------------+-----+
| id|Phase|Switch|InputFileName|Valid|
+---+-----+------+-------------+-----+
|  1|    2|     1|        fileA| true|
|  2|    2|     1|        fileA| true|
|  3|    2|     1|        fileA| true|
|  4|    2|     0|        fileA| true|
|  5|    2|     0|        fileA| true|
|  6|    2|     1|        fileA| true|
| 11|    2|     1|        fileB| true|
| 12|    2|     1|        fileB| true|
| 13|    2|     0|        fileB| true|
| 14|    2|     0|        fileB| true|
| 15|    2|     1|        fileB| true|
| 16|    2|     1|        fileB| true|
| 21|    4|     1|        fileB|false|
| 22|    4|     1|        fileB|false|
| 23|    4|     1|        fileB|false|
| 24|    4|     1|        fileB|false|
| 25|    4|     1|        fileB|false|
| 26|    4|     0|        fileB|false|
| 31|    1|     0|        fileC|false|
| 32|    1|     0|        fileC|false|
+---+-----+------+-------------+-----+