>我有一列充满了包含拆分 http 请求的数组。 我将它们过滤为两种可能性之一:
|[, courses, 27381...|
|[, courses, 27547...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, api, v1, cours...|
|[, courses, 33287...|
|[, courses, 24024...|
在这两种数组类型中,从"课程"开始是相同的数据和结构。
我想使用 case
语句获取数组的切片,如果数组的第一个元素是"api",则取数组末尾的元素 3 ->。 我尝试使用Python切片语法[3:]
,以及正常的PostgreSQL
语法[3, n]
其中n
是数组的长度。 如果它不是"api",那么只需取给定的值。
我理想的最终结果是一个数组,其中每一行共享相同的结构,课程在第一个索引中,以便从该点开始更容易解析。
定义一个UDF
很容易,你之前提出了一个非常相似的问题,所以我不会发布确切的答案让你思考和学习(为了你自己的利益)。
from pyspark.sql.functions import udf
df = sc.parallelize([(["ab", "bs", "xd"],), (["bc", "cd", ":x"],)]).toDF()
getUDF = udf(lambda x, y: x[1:] if x[y] == "ab" else x)
df.select(getUDF(col("_1"), lit(0))).show()
+------------------------+
|PythonUDF#<lambda>(_1,0)|
+------------------------+
| [bs, xd]|
| [bc, cd, :x]|
+------------------------+
假设数据帧中的列称为http_col
,并且数组中的第一项是空字符串,则可能的解决方案是:
df.selectExpr(
"""if(array_contains(http_col, 'api'),
slice(http_col, 4, size(http_col) - 3),
http_col) as cleaned_http_col
"""
)
如果您有 Spark>= 2.4.0,另一个选项可能是:
df.selectExpr(
"array_remove(array_remove(http_col, 'api'), 'v1') as cleaned_http_col"
)