如何在pyspark中动态拆分和分组数字

how to split and group numbers dynamically in pyspark

我在数据框中有以下列,它的数字是 6 位数字和 6 的倍数,我想要实现的是将该列分成 2 个 3 位数字子组的组,因为存在关系。 这是数据框,

+------------------------+---+
|Col1                    |len|
+------------------------+---+
|001200                  |6  |
|201400                  |6  |
|401800                  |6  |
|201400401800            |12 |
|001200201400401800      |18 |
|001200201400401800801999|24 |
+------------------------+---+

我期待的是这样的

+------------------------+-------------------------------+---+
|Col1                    |processed_column               |len|
+------------------------+-------------------------------+---+
|001200                  |001-200                        |6  |
|201400                  |201-400                        |6  |
|401800                  |401-800                        |6  |
|201400401800            |201-400,401-800                |12 |
|001200201400401800      |001-200,201-400,401-800        |18 |
|001200201400401800801999|001-200,201-400,401-800,801-999|24 |
+------------------------+-------------------------------+---+

我能想到的一个解决方案是检查 len 并据此拆分它,但是我必须继续为每个长度编写 F.when 条件并相应地拆分它。

df = df.withColumn(
            "processed_column",
            F.when(
                F.col("len") == 6,
                F.concat(
                    F.substring(F.col("Col1"), 0, 3),
                    F.lit("-"),
                    F.substring(F.col("Col1"), 3, 3),
                ),
            )
            .when(
                F.col("len") == 12,
                F.concat(
                    F.substring(F.col("Col1"), 0, 3),
                    F.lit("-"),
                    F.substring(F.col("Col1"), 4, 3),
                    F.lit(","),
                    F.substring(F.col("Col1"), 7, 3),
                    F.lit("-"),
                    F.substring(F.col("Col1"), 10, 3),
                ),
            )
            .otherwise(F.col("Col1")),
        )

是否有更好的方法可以动态处理此问题?

我不知道 pyspark,但是 Python 中的字符串,您可以这样做以将所有六个字符串的倍数更改为您所问的样式。

def f(s):
    return ','.join([s[i*6:i*6+3]+'-'+s[i*6+3:i*6+6] for i in range(len(s)//6)])
print(f('401800'))
print(f('201400401800'))
print(f('001200201400401800'))
print(f('001200201400401800801999'))

401-800
201-400,401-800
001-200,201-400,401-800
001-200,201-400,401-800,801-999

def myFunction(s):
    return ','.join([s[i*6:i*6+3]+'-'+s[i*6+3:i*6+6] for i in range(len(s)//6)])
udf_myFunction = F.udf(myFunction)
df.withColumn('new_string', udf_myFunction("Col1")).show()