我目前有一个带有id的Dataframe和一个列,该列是一个结构数组:
root
|-- id: string (nullable = true)
|-- lists: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- _1: string (nullable = true)
| | |-- _2: string (nullable = true)
下面是一个包含数据的示例表:
id | list1 | list2
------------------------------------------
1 | [[a, av], [b, bv]]| [[e, ev], [f,fv]]
2 | [[c, cv]] | [[g,gv]]
如何将上面的Dataframe转换为下面的Dataframe?我需要“分解”数组并根据结构中的第一个值添加列。
id | a | b | c | d | e | f | g
----------------------------------------
1 | av | bv | null| null| ev | fv | null
2 | null| null| cv | null|null|null|gv
创建Dataframe的pyspark代码如下:
d1 = spark.createDataFrame([("1", [("a","av"),("b","bv")], [("e", "ev"), ("f", "fv")]), \
("2", [("c", "cv")], [("g", "gv")])], ["id","list1","list2"])
注意:我有一个spark版本的2.2.0,所以一些sql函数不能工作,比如concat\u map等。
2条答案
按热度按时间c9qzyr3d1#
升级版-适用于spark 2.2.0
您可以使用UDF在2.2.0中定义类似的函数。在性能方面,它们的效率要低得多,而且对于每种输出值类型,您都需要一个特殊的函数(即,您将无法拥有一个函数)
element_at
函数,它可以从任何Map类型输出任何类型的值),但它们可以工作。以下代码适用于spark 2.2.0:原始答案(适用于spark 2.4.0+)
不清楚在哪里
d
列来自您的示例(d
从未出现在初始Dataframe中)。如果应该基于数组中的第一个元素创建列,那么这应该是可行的(假设列表中唯一的第一个值的总数足够小):输出(无列)
d
因为它从未在初始Dataframe中提到):如果您真的认为列的列表从一开始就是固定的(并且它们不是从数组中获取的),那么您可以替换varaible的定义
map_keys
列的固定列表,例如。map_keys=['a', 'b', 'c', 'd', 'e', 'f', 'g']
. 在这种情况下,你会得到你在答案中提到的结果:顺便说一句-你想做的不是所谓的
explode
在Spark里。explode
在spark中,用于从一行创建多行的情况。e、 g.如果你想从Dataframe中得到这样的信息:对此:
hgtggwj02#
您可以使用hogher顺序函数来执行此操作,而无需分解数组,如:
希望有帮助