apache-spark - Pyspark 数据框 - 将元组数据转换为行
问题描述
我想将 pyspark 数据框中的元组数据转换为基于两个键的行。给定的是原始数据和预期输出。
架构:
root
|-- key_1: string (nullable = true)
|-- key_2: string (nullable = true)
|-- prod: string (nullable = true)
原始数据:
key_1|key_2|prod
cust1|order1|(p1,p2,)
cust2|order2|(p1,p2,p3)
cust3|order3|(p1,)
预期输出:
key_1|key_2|prod|category
cust1|order1|p1
cust1|order1|p2
cust1|order1|
cust2|order2|p1
cust2|order2|p2
cust2|order2|p3
cust3|order3|p1
cust3|order3|
解决方案
Spark 有一个名为 的函数explode
,允许使用将列表/数组从一行分解为多行,完全符合您的要求。
但是根据您的架构,我们必须再添加一步,将 prod 字符串列转换为数组类型
转换类型的示例代码
from pyspark.sql.functions import explode
from pyspark.sql.functions import udf
from pyspark.sql.types import ArrayType, StringType
def squared(s):
# udf function, convert string (p1,p2,p3) to array [p1, p2, p3]
items = s[1:-2] # Not sure it is correct with your data, please double check
return items.split(',')
# Register udf
squared_udf = udf(squared, ArrayType(StringType()))
# Apply udf to conver prod string to real array
df_2 = df.withColumn('prod_list', squared_udf('prod'))
# Explode prod_list
df_2.select(df.key_1, df.key_2, explode(df_2.prod_list)).show()
我已经测试过,结果是
+-----+------+---+
|key_1| key_2|col|
+-----+------+---+
|cust1|order1| p1|
|cust1|order1| p2|
|cust2|order2| p1|
|cust2|order2| p2|
|cust2|order2| p3|
|cust3|order3| p1|
+-----+------+---+
有样本数据
data = [
{'key_1': 'cust1', 'key_2': 'order1', 'prod': '(p1,p2,)'},
{'key_1': 'cust2', 'key_2': 'order2', 'prod': '(p1,p2,p3,)'},
{'key_1': 'cust3', 'key_2': 'order3', 'prod': '(p1,)'},
]
推荐阅读
- android - 预期为 BEGIN_OBJECT,但在第 1 行第 1 列路径为 STRING $ Android Refrofit
- django - 带有 Django Rest 框架的多部分表单
- python - Python While 循环,对“或”运算符感到困惑
- firebase - 如何提高我的可调用云函数的安全性?
- html - Tailwindcss 和 AlpineJs 过渡问题
- java - 如何在 java 代码中使用 MongoTemplate cond 和 filter?
- java - 如何在不丢失前导零的情况下将 String 转换为 Long
- python - kivy 自定义小部件如何访问使用 kvlang 设置的属性
- python - Spyder 变量资源管理器中的颜色
- prometheus - 在警报时添加 Alertmanager 表达式查询