我有一个广告,我希望用它来映射<v-select ... :item-value="value.language" :item-text="text"></v-select>
中的列值。让我们说我为此调用DataFrame
方法。
我只能使用UDF,但不能直接使用它:
withColumn()
使用文字或使用UDF进行引用可以正常工作:
sc = SparkContext()
ss = SparkSession(sc)
df = ss.createDataFrame( [ "a", "b" ], StringType() ).toDF("key")
# +---+
# |key|
# +---+
# | a|
# | b|
# +---+
thedict={"a":"A","b":"B","c":"C"}
thedict_bc=sc.broadcast(thedict)
但是,直接从命令访问字典并不是:
df.withColumn('upper',lit(thedict_bc.value.get('c',"--"))).show()
# +---+-----+
# |key|upper|
# +---+-----+
# | a| C|
# | b| C|
# +---+-----+
df.withColumn('upper',udf(lambda x : thedict_bc.value.get(x,"--"), StringType())('key')).show()
# +---+-----+
# |key|upper|
# +---+-----+
# | a| A|
# | b| B|
# +---+-----+
我错过了一些明显的东西吗?
答案 0 :(得分:3)
TL; DR 您正在混淆属于完全不同的背景的事物。符号SQL表达式(lit
,col
等)和纯Python代码。
你正在混淆上下文。以下行:
thedict_bc.value.get(col('key'),"--")))
在驱动程序上用Python执行,实际上是一个本地字典查找。 thedict
不包含col('key')
(字面意义,不涉及扩展)您始终获得默认值。
我个人会使用一个简单的join
:
lookup = sc.parallelize(thedict.items()).toDF(["key", "upper"])
df.join(lookup, ["key"], "left").na.fill("upper", "--").show()
+---+-----+
|key|upper|
+---+-----+
| b| B|
| a| A|
+---+-----+
但是udf
(正如您已经建立的那样)或文字map
也会起作用:
from pyspark.sql.functions import coalesce, create_map
from itertools import chain
thedict_col = create_map(*chain.from_iterable(
(lit(k), lit(v)) for k, v in thedict.items()
))
df.withColumn('upper', coalesce(thedict_col[col("key")], lit("--"))).show()
+---+-----+
|key|upper|
+---+-----+
| a| A|
| b| B|
+---+-----+
备注强>:
pyspark.sql.functions.upper
。some_broadcast.value
作为函数的参数将完全不起作用。变量替换将在本地应用,并且不会使用广播。 value
应该在函数体中调用,因此它在执行程序上下文中执行。