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

Spark数据帧-将结构列拆分为2列

松建本
2023-03-14

我有一个包含(我认为是)(String, String)对的数据帧。

它看起来像这样:

> df.show
| Col1 | Col2    |
| A    | [k1, v1]|
| A    | [k2, v2]|

> df.printSchema
|-- _1: string (nullable = true)
|-- _2: struct (nullable = true)
|    |-- _1: string (nullable = true)
|    |-- _2: string (nullable = true)

< code>Col2曾经包含一个< code>Map[String,String],我在上面做了一个< code>toList(),然后做了< code>explode()以获得原始Map中每个映射的一行。


我想将< code>Col2分成2列,并获得以下数据帧:

| Col1 | key    | value |
| A    | k1     | v1    |
| A    | k2     | v2    |

有谁知道如何做到这一点?

或者,有人知道如何将一个映射分解成多行(每个映射一行)和两列(一个键,一个值)。


我尝试使用通常成功的模式(String, String)但这不起作用:

df.select("Col1", "Col2").
   map(r =>(r(0).asInstanceOf[String],
            r(1).asInstanceOf[(String, String)](0),
            r(1).asInstanceOf[(String, String)](1)
           )
       )

Caused by: java.lang.ClassCastException:
org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema cannot be cast to scala.Tuple2

==

即使这有效,也会出现一个问题,即使用索引不是访问元组元素的正确方法......

谢谢!

共有2个答案

萧成文
2023-03-14

您可以添加另一个方法来实现这一点:

df.withColumn("key", $"Col2._1")
  .withColumn("value", $"Col2._2")
唐弘厚
2023-03-14

您可以使用select来投影struct的每个元素以解包它。

df.select($"Col1", $"Col2._1".as("key"), $"Col2._2".as("value"))
 类似资料:
  • 我有一个包含结构数组的嵌套源json文件。结构的数量因行而异,我想使用Spark(scala)从结构的键/值动态创建新的数据框架列,其中键是列名,值是列值。 这里有一个由3个结构组成的数组,但这3个结构需要动态地拆分为3个单独的列(3个的数量可能会有很大的变化),我不知道如何做到这一点。 请注意,数组中的每个数组元素都产生了3个新列。 我认为理想的解决方案与本SO帖子中讨论的类似,但有两个主要区别

  • 我有列。 如何根据值将其拆分为2? 第一个将包含

  • 我正在Spark 3.0.0上执行Spark结构流的示例,为此,我使用了twitter数据。我在Kafka中推送了twitter数据,单个记录如下所示 2020-07-21 10:48:19|1265200268284588034|RT@narendramodi:与@IBM首席执行官@ArvindKrishna先生进行了广泛的互动。我们讨论了几个与技术相关的主题,…|印度海得拉巴 在这里,每个字段

  • 我有下面的spark数据框架。 我必须将上面的数据帧列拆分为多个列,如下所示。 我尝试使用分隔符进行拆分;和限制。但是它也将主题拆分为不同的列。姓名和年龄被组合在一起成一列。我要求所有主题在一列中,只有姓名和年龄在单独的列中。 这在Pyspark有可能实现吗?

  • 问题内容: 我的问题是我有一个这样的表: c1 | c2 | c3 | c4是一个由|分隔的值。 我的最终结果应如下所示: 我该怎么做呢? 谢谢 问题答案: 这就是您可以执行的操作,使用管道将字符串拆分并使用spark函数爆炸数据 输出: 希望这可以帮助!

  • 它是这样的: 插入some_table(col1,col2,col3,col4) 选择col1、col2、my_func(col3)为new_col3、col4 现在我需要使用相同的逻辑返回两个值而不是一个值。 我可以简单地编写另一个函数来执行相同的逻辑并返回第二个值,但这将是昂贵的,因为该函数从一个大的历史表中进行选择。 我不能与历史表进行连接,因为该函数没有执行简单的select。