我有一个 PySpark 数据帧,架构如下所示:
root
|-- useragent: string (nullable = true)
|-- properties: struct (nullable = true)
| |-- browser: string (nullable = true)
| |-- device: string (nullable = true)
我正在使用udf
+ withColumn
从用户代理中提取更多信息。但我只能在新列中存储我正在创建的任何其他属性。有没有办法将其附加到结构本身?
我已经更改了架构,但它不会从已经存在的其他属性传输我需要的所有数据
df = df.schema['properties'].dataType.add(StructField('type', StringType()))
将其转换为RDD是否更有意义?
withField
:
F.col("properties").withField("type", extract_function)
<小时 />完整示例:
from pyspark.sql import functions as F
df = spark.createDataFrame(
[("type=type1,mode=5", ("Chrome", "PC1"))],
"useragent string, properties struct<browser:string,device:string>"
)
df.printSchema()
# root
# |-- useragent: string (nullable = true)
# |-- properties: struct (nullable = true)
# | |-- browser: string (nullable = true)
# | |-- device: string (nullable = true)
df.show()
# +-----------------+-------------+
# | useragent| properties|
# +-----------------+-------------+
# |type=type1,mode=5|{Chrome, PC1}|
# +-----------------+-------------+
df = df.withColumn("properties", F.col("properties").withField(
"type",
F.regexp_extract("useragent", r"type=(w+)", 1)
))
df.printSchema()
# root
# |-- useragent: string (nullable = true)
# |-- properties: struct (nullable = true)
# | |-- browser: string (nullable = true)
# | |-- device: string (nullable = true)
# | |-- type: string (nullable = true)
df.show()
# +-----------------+--------------------+
# | useragent| properties|
# +-----------------+--------------------+
# |type=type1,mode=5|{Chrome, PC1, type1}|
# +-----------------+--------------------+
使用此代码段不会获得任何数据,因为您没有选择任何数据。您在此操作中所做的无非是访问 Schema
属性,以某种方式对其进行修改并将其分配给变量df
(这不是您期望的修改后的数据帧(,而只是一个 StructType 对象(那里似乎有一些语法错误,请检查(
您应该做的是通过select
和合适的转换函数来修改数据帧。您可以考虑创建一个具有所需结构的 StructField
类型的新列,并使用 withColumn
函数将其添加为新列