使用 MapType 文字创建新列

Posted

技术标签:

【中文标题】使用 MapType 文字创建新列【英文标题】:Using MapType literal to create new column 【发布时间】:2020-02-29 20:11:57 【问题描述】:

我有以下pyspark.DataFrame

+---+--------+--------+--------------+
|SEX|_AGEG5YR|_IMPRACE|       _LLCPWT|
+---+--------+--------+--------------+
|  2|    11.0|     1.0| 79.4259469451|
|  2|    10.0|     1.0| 82.1648291655|
|  2|    11.0|     2.0| 55.7851100058|
|  2|    13.0|     1.0|115.9818718258|
|  2|    12.0|     1.0|194.7566575195|
+---+--------+--------+--------------+

我想根据 SEX 列创建一个新列 正如by this previous answer 所建议的那样,我已经定义了一个MapType 文字如下

brfss_mapping = 
    "SEX": 
        1: "Male",
        2: "Female",
        9: "Refused"
    

brfss_sex_mapping = create_map(
    [lit(x) for x in chain(*brfss_mapping["SEX"].items())]
)

现在,当我使用具有常量值的withColumnbrfss_sex_mapping.getItem(...) 时,如下所示

brfss_dmy = brfss_dmy.withColumn(
    "SEX_2",
    brfss_sex_mapping.getItem(1)
)

我得到了预期的结果

+---+--------+--------+--------------+-----+                                    
|SEX|_AGEG5YR|_IMPRACE|       _LLCPWT|SEX_2|
+---+--------+--------+--------------+-----+
|  1|    13.0|     1.0|381.8001043164| Male|
|  2|    10.0|     1.0| 82.1648291655| Male|
|  1|    11.0|     1.0|279.1864457296| Male|
|  1|    10.0|     1.0| 439.024136158| Male|
|  2|     8.0|     1.0| 372.921644978| Male|
+---+--------+--------+--------------+-----+

但是,当我尝试按如下方式传递适当的列时(再次,正如上一个答案中所建议的那样)

brfss_dmy = brfss_dmy.withColumn(
    "SEX_2",
    brfss_sex_mapping.getItem(col("SEX"))
)

我得到以下信息 java.lang.RuntimeException: Unsupported literal type class org.apache.spark.sql.Column SEX

【问题讨论】:

我无法重现您提供的示例。我正在使用 Spark 2.4 @Lamanus brfss_sex_mapping.getItem("SEX") 为每一行返回 null。我认为它会尝试访问键为“SEX”的值,如果未定义。 @blackbishop 我正在使用 Spark 3.0 @PierrePasquet ***.com/posts/42983199/revisions 我错了,对不起,上面的链接真的很好。 【参考方案1】:

似乎在 Spark 3.0 中,我们无法再将列传递给 getItem 函数,但我在代码或文档中找不到任何参考。

您可以改用element_at

df.withColumn("SEX_2", element_at(brfss_sex_mapping, col("SEX")).show()

或者以数组的形式访问值:

df.withColumn("SEX_2", brfss_sex_mapping[col("SEX")]).show()

在 Scala 中:

df.withColumn("SEX_2", element_at(brfss_sex_mapping, $"SEX")).show()
df.withColumn("SEX_2", brfss_sex_mapping($"SEX")).show()

【讨论】:

以上是关于使用 MapType 文字创建新列的主要内容,如果未能解决你的问题,请参考以下文章

pyspark:从现有列创建 MapType 列

在pyspark中展平Maptype列

Spark DataFrame ArrayType 或 MapType 用于检查列中的值

MapType 列值上的 PySpark 杠杆函数

如何从 Pyspark 中的 MapType 列获取键和值

google mapView 样式在具有 maptype=TERRAIN 的 Android 上不起作用