Pyspark -列转换导致数据重排

nhaq1z21  于 2023-02-03  发布在  Spark
关注(0)|答案(1)|浏览(87)

我试图转换Pyspark Dataframe 中的数据以便导出它。我有像"[1,2,3]"这样的数组,我需要将它转换为像"(1;2; 3)"。数组需要连接,并且应该在数组的开头和结尾添加括号。我还需要应用一些正则表达式。
输入示例如下:
| 列1|数组1|列2|
| - ------|- ------|- ------|
| "第一次"|[一、二、三]|"阿~"|
| "第二次"|[四、五、六]|"乙"|
例外输出:
| 列1|数组1|列2|
| - ------|- ------|- ------|
| "第一次"|(一、二、三)|"一个"|
| "第二次"|(四、五、六)|"乙"|
实际错误输出:
| 列1|数组1|列2|
| - ------|- ------|- ------|
| "第一次"|(四、五、六)|"一个"|
| "第二次"|(X; X; X)|"乙"|
其中"(X; X;X)"将是来自另一行的数据。
我尝试了以下代码:

for c in df.columns:
    if isinstance(df.schema[c].dataType, ArrayType):
        print(c)
        df= df.withColumn(c, concat_ws(';', col(c))).withColumn(c, concat(lit("("), col(c), lit(")"))).withColumn(c, F.regexp_replace(c, '\n|\r|\\n|\\r|~|\\(\\)|', ''))
    else:
        df= df.withColumn(c, F.regexp_replace(c, '\n|\r|\\n|\\r|~|', ''))

我在PysparkDataframe的每一列上都做一个循环,如果列是一个数组,我将它连接起来并应用regexp,如果不是,我只应用regexp。
问题是,在这些操作之后,数据在我的列中被打乱,并且我没有例外的数据。例如,如果列d的给定行的值是"b",那么现在同一行的值将是"c"或"d"。
如何在不"打乱"数据的情况下应用这些转换?我不确定在每列上实际循环的方式是否是使用PySpark的一个很好的实践,但我确实需要在每列上应用我的函数,并检查它是否是数组以适应处理。

c8ib6hqw

c8ib6hqw1#

根据您的数据,数据框如下所示:

a = [
    ("First", [1, 2, 3], "a~"),
    ("Second", [4, 5, 6], "b"),
]

b = "col1   array1  col2".split()

df = spark.createDataFrame(a,b)

df.show()

+------+---------+----+
|  col1|   array1|col2|
+------+---------+----+
| First|[1, 2, 3]|  a~|
|Second|[4, 5, 6]|   b|
+------+---------+----+

我试过你的密码了。没问题:

from pyspark.sql import functions as F, types as T

for c in df.columns:
    if isinstance(df.schema[c].dataType, T.ArrayType):
        print(c)
        df = (
            df.withColumn(c, F.concat_ws(";", F.col(c)))
            .withColumn(c, F.concat(F.lit("("), F.col(c), F.lit(")")))
            .withColumn(c, F.regexp_replace(c, "\n|\r|\\n|\\r|~|\\(\\)|", ""))
        )
    else:
        df = df.withColumn(c, F.regexp_replace(c, "\n|\r|\\n|\\r|~|", ""))

df.show()

+------+-------+----+
|  col1| array1|col2|
+------+-------+----+
| First|(1;2;3)|   a|
|Second|(4;5;6)|   b|
+------+-------+----+

相关问题