python - 更新 Pyspark 中地图类型列的结构化值
问题描述
我正在尝试修改 Map 类型的 Dataframe 列,其值依次为 Struct 类型:
root
|-- name: string (nullable = true)
|-- age: long (nullable = true)
|-- MapName: map (nullable = true)
| |-- key: string
| |-- value: struct (valueContainsNull = true)
| | |-- field1: double (nullable = true)
| | |-- field2: double (nullable = true)
我以 MapName 列初始化为 None 的方式创建了 DataFrame,因为我需要在以后的阶段填写信息。我使用的代码如下:
from pyspark.sql import SparkSession, DataFrame
from pyspark.sql.functions import col, udf, lit
from pyspark.sql.types import StructType, StringType, LongType, DoubleType, MapType
spark = SparkSession.builder.appName("testMapType").getOrCreate()
data = [('Alice', 1)]
df = spark.createDataFrame(data, ['name','age'])
def value_struct():
schema = StructType([
StructField('field1', DoubleType(), True),
StructField('field2', DoubleType(), True)])
return schema
myschema = StructType([
StructField('name', StringType(), True),
StructField('age', LongType(), True),
StructField('MapName', MapType(StringType(), value_struct()), True)])
df = df.withColumn('MapName',lit(None).cast(MapType(StringType(), value_struct())))
df = spark.createDataFrame(df.rdd, schema=myschema)
df.printSchema()
现在,当我尝试使用这样的 udf 更新 MapName 列时:
my_update_udf = udf(lambda x: {**x, **{'a_map_key':{'field1':3.2,'field2':2.6}}}, MapType(StringType(), value_struct()))
df2 = df.withColumn('MapName', my_update_udf(col('MapName')))
df2.collect()
我收到以下错误:
TypeError: 'NoneType' object is not a mapping
我从过去的询问中找不到任何建议,这里有什么帮助吗?
解决方案
为此,您不需要 UDF。您可以使用相关的 Spark SQL 函数来创建映射和结构。
import pyspark.sql.functions as F
new_map = F.create_map(
F.lit('a_map_key'),
F.struct(
F.lit(3.2).alias('field1'),
F.lit(2.6).alias('field2')
)
)
df2 = df.withColumn(
'MapName',
F.when(
F.col('MapName').isNotNull(), # need to check null because
F.map_concat('MapName', new_map) # map_concat doesn't work if map is null
).otherwise(new_map)
)
df2.show(truncate=False)
+-----+---+-------------------------+
|name |age|MapName |
+-----+---+-------------------------+
|Alice|1 |[a_map_key -> [3.2, 2.6]]|
+-----+---+-------------------------+
推荐阅读
- c++ - 检查是否存在 operator()
- html - Flexbox - 如何防止长文本向右移动 div?
- java - 通过 Selenium 启动浏览器时出现异常 java.lang.ClassNotFoundException: org.openqa.selenium.MutableCapabilities
- python - 为什么在添加使用 Builder.load_string() 创建的小部件后没有捕获到这个 kivy 错误?
- ios - Vscode React Native 在设备上运行
- excel - excel使用vlookup使用另一列将两个表中的两列配对
- javascript - 捆绑和缩小以及异步/等待
- c# - 如果不在 .NET Core 中,是否可以引用解决方案中存在的项目并使用 NuGet 包引用作为后备?
- python - 如何实例化现有的 QGIS 插件工具栏
- zig - 预期类型 ?extern fn