如何从 PySpark 列中子字符串的左侧和同一子字符串的右侧提取字符?

How to extract characters from a left of a substring and right of the same substring in PySpark column?

我的 Pyspark 数据框是这样的:

|ID|A|
+--+-------+
|1|7800028|
|2|700024|
|3|720004|
|4|70004|
|5|700004|

我想删除同时出现的 3 个零,并在单独的列中获取三个零左右两侧的数字。 像这样:

|ID|B|C
+--+-------+
|1|78|28|
|2|7|24|
|3|72|4|
|4|7|4|
|5|70|4

问题是列 A 的长度可以变化,B 中的值范围为 0-99,C 中的值范围为 0-99。 因此我似乎无法使用 substring 来获取 B。C 仍然可以通过 substring 函数实现。

使用 PySpark split() 函数拆分“A”列中的值。参考:https://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=split#pyspark.sql.functions.split

data = [[1, 7800028], [2, 700024], [3, 720004], [4, 70004]]
data_df = spark.createDataFrame(data, ["ID", "A"])
data_df.show()

+---+-------+-------+
| ID|      A|    new|
+---+-------+-------+
|  1|7800028|7800028|
|  2| 700024| 700024|
|  3| 720004| 720004|
|  4|  70004|  70004|
+---+-------+-------+
from pyspark.sql import functions as F

new_df = (data_df
           .withColumn("B", F.split(data_df["A"].cast("string"), "000")[0])
           .withColumn("C", F.split(data_df["A"].cast("string"), "000")[1])
          )
new_df.show()

+---+-------+---+---+
| ID|      A|  B|  C|
+---+-------+---+---+
|  1|7800028| 78| 28|
|  2| 700024|  7| 24|
|  3| 720004| 72|  4|
|  4|  70004|  7|  4|
+---+-------+---+---+

您可以使用模式 000(?=[1-9]|0$) 来拆分字符串,其中 (?=[1-9]|0$) 是一个锚点,以确保最后一个 0 必须跟在 non-zero 数字或零作为整数的最后一位,例如:

spark.sql("""
    with t as ( 
        select *, split(A,'000(?=[1-9]|0$)') as arr
        from values (1,7800028),(2,700024),(3,720004),(4,70004),(5,700004),(6,120000) as (id,A)
    ) 
    select id, A, arr[0] as B, arr[1] as C 
    from t
""").show()
+---+-------+---+---+
| id|      A|  B|  C|
+---+-------+---+---+
|  1|7800028| 78| 28|
|  2| 700024|  7| 24|
|  3| 720004| 72|  4|
|  4|  70004|  7|  4|
|  5| 700004| 70|  4|
|  6| 120000| 12|  0|
+---+-------+---+---+