当前位置: 首页 > 知识库问答 >
问题:

如何用前缀爆炸结构列?

宦砚
2023-03-14

我的目标是分解(即,从结构内部获取它们,并将它们作为数据集的剩余列)一个Spark结构列(已经完成),但通过在任意字符串前面添加前缀来更改内部字段名。其中一个动机是,我的结构可以包含与它外部的列同名的列,因此,我需要一种容易区分它们的方法。当然,我事先不知道结构中的列是什么。

以下是我目前掌握的情况:

  implicit class Implicit(df: DataFrame) {
    def explodeStruct(column: String) = df.select("*", column + ".*").drop(column)
  }

这做的工作好-我用这样写:

  df.explodeStruct("myColumn")

它返回原始数据帧中的所有列,以及末尾结构的内部列。

至于前置前缀,我的想法是取列,找出它的内部列是什么。我浏览了文档,在Column类上找不到任何这样做的方法。然后,我改变了方法,采用DataFrame的模式,然后按列名过滤结果,并从结果数组中提取找到的列。问题是,我找到的这个元素具有StructField类型——同样,它没有提供提取其内部字段的选项——而我真正想要的是处理StructType元素——它具有< code >。getFields方法,这正是我想要的(也就是说,向我显示内部列的名称,这样我就可以遍历它们并在我的select中使用它们,在它们前面加上我想要的前缀)。我不知道如何将StructField转换为StructType。

我的最后一次尝试是解析StructField.toString的输出——它包含内部列的所有名称和类型,尽管这感觉很肮脏,我宁愿避免这种低级的方法。

这个问题有什么优雅的解决方案吗?

共有2个答案

鲜于阳
2023-03-14

如果有人感兴趣,下面是PySpark的一些类似内容:

def explode_struct(df: DataFrame, column: str) -> DataFrame:
    original_position = df.columns.index(column)

    original_columns = df.columns
    new_columns = df.select(column + ".*").columns
    exploded_columns = [F.col(column + "." + c).alias(column + "_" + c) for c in new_columns]

    col_list = [F.col(c) for c in df.columns]
    col_list.pop(original_position)
    col_list[original_position:original_position] = exploded_columns

    return df.select(col_list)
莫欣悦
2023-03-14

好吧,在再次阅读了我自己的问题后,我想出了一个优雅的问题解决方案——我只需要按照我的方式选择所有列,然后将其与原始数据帧进行比较,以找出哪些是新列。这是最终的结果——我还做了这个,这样分解的列就会显示在与原始结构相同的地方,这样就不会破坏信息流:

  implicit class Implicit(df: DataFrame) {
    def explodeStruct(column: String) = {
      val prefix = column + "_"
      val originalPosition = df.columns.indexOf(column)

      val dfWithAllColumns = df.select("*", column + ".*")

      val explodedColumns = dfWithAllColumns.columns diff df.columns
      val prefixedExplodedColumns = explodedColumns.map(c => col(column + "." + c) as prefix + c)

      val finalColumnsList = df.columns.map(col).patch(originalPosition, prefixedExplodedColumns, 1)

      df.select(finalColumnsList: _*)
    }
  }

当然,您可以自定义前缀、分隔符等,但这很简单,任何人都可以调整参数等。用法保持不变。

 类似资料:
  • 问题内容: 我已经做过了,但是没有用。每当我访问它时,它都会转到。代码在这里给出: *我也添加了 *更新,但没有区别。另外,让我告诉您,我正在地址栏中输入地址,然后按Enter。我说的对吗?浏览器如何发现它不需要从服务器刷新? 更新#2 理想的情况是我想要的网址为和到。现在给出404 更新#3 我正在使用nginx代理,如果有帮助的话。 更新#4 擦除的缓存。现在我可以看到,而不是,但仍给404

  • 问题内容: 下面是表2中的数据 我可以使用以下查询来爆炸以上数据,并且对于以上数据也可以正常工作- 这样我会得到很好的输出 但是在某些情况下,我在下表中有这样的数据,对于相同的product_id- 我需要使用HiveQL查询为上述数据输出类似的结果- 这有可能做到这一点吗? 任何建议将不胜感激。 PS我几天前问这个问题,但是在这种情况下,数据是不同的,现在数据完全不同了,我需要类似的输出。 问题

  • 问题内容: 我有这样的桌子 这样我就可以轻松执行查询 我得到 我想生成一个这样的表 请注意,我要显示爆炸行。另外,对于多个ID,可能会重复,因此我希望这些行反映出来。基本上,+ 应该是唯一的。 我该如何写查询?我试过了 但是我得到了 问题答案: 使用 侧面图 : 结果: 使用表而不是子查询。

  • 问题内容: 我有一个表名消息。我需要获取一个列名,其中 receiver_id = 4, 但我总是得到空输出。 屏幕截图上方有3行。第二行和第三行与其他ID一起存在,我需要对其进行分解并显示第二行和第三行记录。 如何编写MySQL查询? 问题答案: 存储逗号分隔值确实是一个糟糕的设计,您应该 首先将接收方的所有关联存储在联结表中,如果您无法更改架构,则可以针对当前情况在逗号分隔列表中搜索值

  • 问题内容: 我一直非常依赖CSS来开发我正在工作的网站。现在,所有CSS样式都在每个标记的基础上应用,因此现在我尝试将其移至更多外部样式中,以帮助将来进行任何更改。 但是现在的问题是,我注意到我遇到了“ CSS爆炸”。对我来说,决定如何最好地组织和抽象CSS文件中的数据变得越来越困难。 我正在从大量基于表格的网站中使用网站中的大量标签。因此,我得到了许多如下所示的CSS选择器: 还算不错,但是作为

  • 问题内容: 我想从包含单词列表的DataFrame转换为每个单词都在其自己行中的DataFrame。 如何在DataFrame中的列上爆炸? 这是我尝试的一些示例,您可以在其中取消注释每个代码行并获取以下注释中列出的错误。我在带有Spark 1.6.1的Python 2.7中使用PySpark。 请指教 问题答案: 和是SQL函数。两者都在SQL上运行。将Java正则表达式作为第二个参数。如果要在