使用 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())]
)
现在,当我使用具有常量值的withColumn
和brfss_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 @Lamanusbrfss_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 文字创建新列的主要内容,如果未能解决你的问题,请参考以下文章