Apache spark 使用内置的spark SQL将映射数组合并/连接到一个映射中
考虑以下数据帧。在这里,我希望将贴图数组合并到一个贴图中,而不使用UDFApache spark 使用内置的spark SQL将映射数组合并/连接到一个映射中,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,考虑以下数据帧。在这里,我希望将贴图数组合并到一个贴图中,而不使用UDF +---+------------------------------------+ |id |greek | +---+------------------------------------+ |1 |[{alpha -> beta}, {gamma -> delta}] | |2 |[{epsilon -> zeta}, {etha -
+---+------------------------------------+
|id |greek |
+---+------------------------------------+
|1 |[{alpha -> beta}, {gamma -> delta}] |
|2 |[{epsilon -> zeta}, {etha -> theta}]|
+---+------------------------------------+
我想我已经试过了所有的映射函数。我想我可以从_条目映射_,但它只是抛出了一个异常,它说它需要映射而不是映射数组
虽然我知道使用UDF很容易做到这一点,但我发现很难相信没有更简单的方法
可运行的python代码
我想有一种方法可以使用内置的
聚合:
import pyspark.sql.functions as F
## Aggregate needs a column with the array to be iterated,
## an initial value and a merge function.
## For the initial value, we need an empty map with corresponding map schema
## which evaluates to (map<string,string>) in this case
map_schema = df.selectExpr('greek[0]').dtypes[0][1]
## F.create_map() creates a 'map<null,null>' type.
empty_map = F.create_map().cast(map_schema)
df.withColumn("Concated",
F.aggregate(
# Values to iterate
col=F.col("greek"),
# Initial value
initialValue=empty_map,
merge = lambda acc, el: F.map_concat(acc, el)
)
)
我想有一种方法可以使用内置的聚合:
import pyspark.sql.functions as F
## Aggregate needs a column with the array to be iterated,
## an initial value and a merge function.
## For the initial value, we need an empty map with corresponding map schema
## which evaluates to (map<string,string>) in this case
map_schema = df.selectExpr('greek[0]').dtypes[0][1]
## F.create_map() creates a 'map<null,null>' type.
empty_map = F.create_map().cast(map_schema)
df.withColumn("Concated",
F.aggregate(
# Values to iterate
col=F.col("greek"),
# Initial value
initialValue=empty_map,
merge = lambda acc, el: F.map_concat(acc, el)
)
)
使用高阶函数的另一个版本:
map\u schema=df.selectExpr('希腊文[0])。数据类型[0][1]
expr=“REDUCE(希腊语,cast(map()为{schema}),(acc,el)->map_concat(acc,el))”。格式(schema=map_schema)
df=带柱的df(“混凝土”,F.expr(expr))
输出:
+---+------------------------------------+--------------------------------+
|id |greek |Concated |
+---+------------------------------------+--------------------------------+
|1 |[{alpha -> beta}, {gamma -> delta}] |{alpha -> beta, gamma -> delta} |
|2 |[{epsilon -> zeta}, {etha -> theta}]|{epsilon -> zeta, etha -> theta}|
+---+------------------------------------+--------------------------------+
使用高阶函数的另一个版本:
map\u schema=df.selectExpr('希腊文[0])。数据类型[0][1]
expr=“REDUCE(希腊语,cast(map()为{schema}),(acc,el)->map_concat(acc,el))”。格式(schema=map_schema)
df=带柱的df(“混凝土”,F.expr(expr))
输出:
+---+------------------------------------+--------------------------------+
|id |greek |Concated |
+---+------------------------------------+--------------------------------+
|1 |[{alpha -> beta}, {gamma -> delta}] |{alpha -> beta, gamma -> delta} |
|2 |[{epsilon -> zeta}, {etha -> theta}]|{epsilon -> zeta, etha -> theta}|
+---+------------------------------------+--------------------------------+
我的方法是分解父列表,分解键,分解值,然后将它们合并在一起
(df
.withColumn('g',F.explode('希腊文'))
.withColumn('k',F.explode(F.map_键('g'))
.withColumn('v',F.explode(F.map_值('g'))
.groupBy('id'))
阿格先生(
F.收集列表('k')。别名('key'),
F.收集列表(“v”).别名(“值”)
)
.withColumn('single_map',(F.map_from_数组('key','value'))
.show(10,False)
)
# +---+---------------+-------------+--------------------------------+
#| id |键|值|单|映射|
# +---+---------------+-------------+--------------------------------+
#| 1 |[alpha,gamma]|[beta,delta]|{alpha->beta,gamma->delta}|
#| 2 |[epsilon,etha]|[zeta,theta]|{epsilon->zeta,etha->theta}|
# +---+---------------+-------------+--------------------------------+
我的方法是分解父列表,分解键,分解值,然后将它们合并在一起
(df
.withColumn('g',F.explode('希腊文'))
.withColumn('k',F.explode(F.map_键('g'))
.withColumn('v',F.explode(F.map_值('g'))
.groupBy('id'))
阿格先生(
F.收集列表('k')。别名('key'),
F.收集列表(“v”).别名(“值”)
)
.withColumn('single_map',(F.map_from_数组('key','value'))
.show(10,False)
)
# +---+---------------+-------------+--------------------------------+
#| id |键|值|单|映射|
# +---+---------------+-------------+--------------------------------+
#| 1 |[alpha,gamma]|[beta,delta]|{alpha->beta,gamma->delta}|
#| 2 |[epsilon,etha]|[zeta,theta]|{epsilon->zeta,etha->theta}|
# +---+---------------+-------------+--------------------------------+
您可以尝试使用F.create_map().cast('map')
作为initialValue
并在不使用slicingAwesome的情况下执行,@mck。如果您知道从该列获取映射模式/类型的任何干净方法,那么这将是非常棒的df.selectExpr('greek[0]')。dtypes[0][1]
记住设置spark.conf.set('spark.sql.mapkeydeduplocy','LAST_WIN')
选项如果你想合并重复的键,你可以尝试使用F.create_map().cast('map')
作为初始值
,并且不使用slicingAwesome来执行,@mck。如果您知道从该列获取映射模式/类型的任何干净方法,那么这将是非常棒的df.selectExpr('greek[0]')。dtypes[0][1]
如果要合并重复密钥,请记住设置spark.conf.set('spark.sql.mapkeydeduplocy','LAST_WIN')
选项