Hive 合并配置单元中具有不同结构的两列

Hive 合并配置单元中具有不同结构的两列,hive,pyspark,hiveql,pyspark-sql,Hive,Pyspark,Hiveql,Pyspark Sql,我已经加载了一个拼花地板文件并创建了一个数据框,如下所示 ---------------------------------------------------------------------- time | data1 | data2 ----------------------------------------------------------------------- 1-40 | [ lion-> 34, bear -> 2 ] |

我已经加载了一个拼花地板文件并创建了一个数据框,如下所示

----------------------------------------------------------------------
 time |  data1                | data2
-----------------------------------------------------------------------
1-40  | [ lion-> 34, bear -> 2 ] |  [ monkey -> [9,23], goose -> [4,5] ]
因此,data1列的数据类型是
string->integer
map,其中data2列的数据类型是
string->array
map

我想把上面的数据框分解成下面的结构

------------------------
time | key        | val
------------------------
1-40 | lion       | 34
1-40 | bear       | 2
1-40 | monkey_0   | 9
1-40 | monkey_1   | 23
1-40 | goose_0    | 4
1-40 | goose_1    | 5
我试图通过在pyspark中使用UDF将data1和data2转换为与
string->array
相同的数据类型,然后分解列,如下所示

def to_map(col1, col2):
    for i in col1.keys():
        col2[i] = [col1[i]]
    return col2
caster= udf(to_map,MapType(StringType(),ArrayType(IntegerType())))
pm_df = pm_df.withColumn("animals", caster('data1', 'data2'))
pm_df.select('time',explode(col('animals')))
我还尝试使用配置单元sql,假设配置单元sql比使用pyspark UDF具有更高的性能

rdd = spark.sparkContext.parallelize([[datetime.datetime.now(), {'lion': 34, 'bear': 2}, {'monkey': [9, 23], 'goose':[4,5]} ]])
df = rdd.toDF(fields)
df.createOrReplaceTempView("df")
df = spark.sql("select time, explode(data1), data2 from df")
df.createOrReplaceTempView("df")
df = spark.sql("select time,key as animal,value,posexplode(data2) from df").show(truncate=False)
但我被以下结果困扰,不知道如何根据我的要求合并拆分的列。上述配置单元sql的输出为:

+--------------------------+------+-----+---+------+-------+
|time                      |animal|value|pos|key   |value  |
+--------------------------+------+-----+---+------+-------+
|2019-06-12 19:23:00.169739|bear  |2    |0  |goose |[4, 5] |
|2019-06-12 19:23:00.169739|bear  |2    |1  |monkey|[9, 23]|
|2019-06-12 19:23:00.169739|lion  |34   |0  |goose |[4, 5] |
|2019-06-12 19:23:00.169739|lion  |34   |1  |monkey|[9, 23]|
+--------------------------+------+-----+---+------+-------+

我知道,在使用python UDF时,python处理器和JVM之间的通信会有很多开销。是否有任何方法可以使用内置函数或配置单元sql实现上述预期结果。

我将分别处理
data1
data2
,然后联合结果集:

from pyspark.sql import functions as F

df1 = df.select('time', F.explode('data1').alias('key', 'value'))
>>> df1.show()
#+--------------------+----+-----+
#|                time| key|value|
#+--------------------+----+-----+
#|2019-06-12 20:19:...|bear|    2|
#|2019-06-12 20:19:...|lion|   34|
#+--------------------+----+-----+

df2 = df.select('time', F.explode('data2').alias('key', 'values')) \
        .select('time', 'key', F.posexplode('values').alias('pos','value')) \
        .select('time', F.concat('key', F.lit('_'), 'pos').alias('key'), 'value')
>>> df2.show()
#+--------------------+--------+-----+
#|                time|     key|value|
#+--------------------+--------+-----+
#|2019-06-12 20:19:...| goose_0|    4|
#|2019-06-12 20:19:...| goose_1|    5|
#|2019-06-12 20:19:...|monkey_0|    9|
#|2019-06-12 20:19:...|monkey_1|   23|
#+--------------------+--------+-----+

df_new = df1.union(df2)