Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.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 如何在一行中左键联接两个结构数组?_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Apache spark 如何在一行中左键联接两个结构数组?

Apache spark 如何在一行中左键联接两个结构数组?,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我和你一起工作 Facebook没有将“购买行为”和“购买行为值$amount”放在同一列中,因此我需要根据我的案例中“操作id+设备类型”的标识符加入到我这一行中 如果每个操作都只是它自己的行,那么用SQL连接它们当然很简单。但是在这种情况下,我需要在每一行中连接两个结构。我要做的是在两个结构之间进行左连接,在两个列上进行匹配。理想情况下,我可以单独使用SQL而不是PySpark/Scala/等 到目前为止,我已经尝试: 这个这为我提供了每个操作各自的行,但由于原始数据集中的父行没有唯一标识符

我和你一起工作

Facebook没有将“购买行为”和“购买行为值$amount”放在同一列中,因此我需要根据我的案例中“操作id+设备类型”的标识符加入到我这一行中

如果每个操作都只是它自己的行,那么用SQL连接它们当然很简单。但是在这种情况下,我需要在每一行中连接两个结构。我要做的是在两个结构之间进行左连接,在两个列上进行匹配。理想情况下,我可以单独使用SQL而不是PySpark/Scala/等

到目前为止,我已经尝试:

这个这为我提供了每个操作各自的行,但由于原始数据集中的父行没有唯一标识符,因此无法按行连接这些结构。还尝试在两列上使用内联,但一次只能使用一个生成器函数。 使用来组合它们。但这不起作用,因为顺序并不总是一样的,而且它们有时没有相同的键。 我考虑在PySpark中编写一个映射函数。但是map函数似乎只通过索引而不是名称来标识列,如果以后在使用第三方API时列可能会发生更改,这似乎很脆弱。 我考虑写一个,这似乎是最好的选择,但需要一个权限,我没有选择匿名功能。如果这真的是最好的选择,我会努力争取这一许可。 为了更好地说明:我的数据集中的每一行都有一个actions和action\u values列,其中包含如下数据

行动=[ { 操作设备:桌面, 操作类型:场外转换.custom.123, 价值:1 }, { 操作设备:桌面,/*相同的转换ID;不同的设备*/ 操作类型:场外转换.custom.321, 价值:1 }, { 操作设备:iphone,/*相同的转换ID;不同的设备*/ 操作类型:场外转换.custom.321, 价值:2 } { 动作\u设备:iphone,/*有动作,但没有动作\u值*/ 操作类型:场外转换.custom.789, 价值:1 }, ] 动作\u值=[ { 操作设备:桌面, 操作类型:场外转换.custom.123, 价值:49.99 }, { 操作设备:桌面, 操作类型:场外转换.custom.321, 价值:19.99 }, { 行动单元设备:iphone, 操作类型:场外转换.custom.321, 数值:99.99 } ] 我希望每行在一个结构中都有两个数据点,如下所示:

我的期望结果=[ { 操作设备:桌面, 操作类型:场外转换.custom.123, 计数:1,/*这来自操作结构*/ 值:49.99/*来自action_values结构*/ }, { 操作设备:桌面, 操作类型:场外转换.custom.321, 计数:1, 价值:19.99 }, { 行动单元设备:iphone, 操作类型:场外转换.custom.321, 计数:2, 数值:99.99 }, { 行动单元设备:iphone, 操作类型:场外转换.custom.789, 计数:1, value:null/*null,因为转换789和iphone没有值*/ } ] IIUC,您可以尝试然后使用,通过匹配动作\设备和动作\类型,从动作\值中查找第一个匹配项:

df.printSchema()
root
 |-- action_values: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- action_device: string (nullable = true)
 |    |    |-- action_type: string (nullable = true)
 |    |    |-- value: string (nullable = true)
 |-- actions: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- action_device: string (nullable = true)
 |    |    |-- action_type: string (nullable = true)
 |    |    |-- value: string (nullable = true)

df.createOrReplaceTempView("df_table")

spark.sql("""

  SELECT       
    transform(actions, x -> named_struct(
      'action_device', x.action_device,
      'action_type', x.action_type,
      'count', x.value,
      'value', filter(action_values, y -> y.action_device = x.action_device AND y.action_type = x.action_type)[0].value
    )) as result
  FROM df_table

""").show(truncate=False)
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|result                                                                                                                                                                                                  |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|[[desktop, offsite_conversion.custom.123, 1, 49.99], [desktop, offsite_conversion.custom.321, 1, 19.99], [iphone, offsite_conversion.custom.321, 2, 99.99], [iphone, offsite_conversion.custom.789, 1,]]|
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
更新:如果是完全联接,可以尝试以下SQL:

spark.sql("""

  SELECT

  concat(
    /* actions left join action_values with potentially multiple matched values */
    flatten(
      transform(actions, x ->
        transform(
          filter(action_values, y -> y.action_device = x.action_device AND y.action_type = x.action_type),
          z -> named_struct(
            'action_device', x.action_device,
            'action_type', x.action_type,
            'count', x.value,
            'value', z.value
          )
        )
      )
    ),
    /* action_values missing from actions */
    transform(
      filter(action_values, x -> !exists(actions, y -> x.action_device = y.action_device AND x.action_type = y.action_type)),
      z -> named_struct(
        'action_device', z.action_device,
        'action_type', z.action_type,
        'count', NULL,
        'value', z.value
      )
    )
  ) as result

  FROM df_table

""").show(truncate=False)

我不知道我怎么会错过SparkSQL文档中的transform函数。这(几乎)正是我想要的!仍然存在一种潜在的边缘情况,即存在一个action_值,该值与一个action不相关,或者比我在问题中没有明确说明的action值更多。我也许可以用另一种方法来解决这个问题,但我很好奇你是否有什么想法。你能调整你的例子以包括这些案例和预期的结果吗?问题更新了。很抱歉给您带来困惑,谢谢您的帮助!我在您的更新中看到一个新条目,其action_值未在actions中显示。您希望如何处理多个操作,将它们作为自己的条目?我将恢复我的更新,澄清这只是我需要的左连接,因为我将您的答案标记为解决方案。结果你比我更了解我的问题: