【问题标题】:Split 1 long txt column into 2 columns in pyspark:databricks在 pyspark:databricks 中将 1 个长文本列拆分为 2 列
【发布时间】:2020-05-26 14:32:49
【问题描述】:

我有一个 pyspark 数据框列,其中包含如下数据。

event_list
PL:1547497782:1547497782~ST:1548593509:1547497782
PU:1547497782:1547497782~MU:1548611698:1547497782:1~MU:1548612195:1547497782:0~ST:1548627786:1547497782
PU:1547497782:1547497782~PU:1547497782:1547497782~ST:1548637508:1547497782
PL:1548631949:0
PL:1548619200:0~PU:1548623089:1548619435~PU:1548629541:1548625887~RE:1548629542:1548625887~PU:1548632702:1548629048~ST:1548635966:1548629048
PL:1548619583:1548619584~ST:1548619610:1548619609
PL:1548619850:0~ST:1548619850:0~PL:1548619850:0~ST:1548619850:0~PL:1548619850:1548619851~ST:1548619856:1548619855

我只对PL: 之后的前 10 位数字和ST: 之后的前 10 位数字感兴趣(如果存在)。对于 PL 拆分,我使用了

df.withColumn('PL', split(df['event_list'], '\:')[1]) 

对于 ST:由于记录的长度不同,逻辑不起作用,我可以使用它

df.withColumn('ST', split(df['event_list'], '\ST:')[1]) 

它返回ST:1548619856:1548619855 并再次拆分第一部分。我有 150 万条记录,所以我想知道是否有更好的方法。

这是预期的输出

PL              ST
154749778   1548593509
    null    1548627786
    null    1548637508
154863194   null
154861920   1548635966
154861958   1548619610
154861985   1548619856 

【问题讨论】:

    标签: apache-spark pyspark apache-spark-sql databricks


    【解决方案1】:

    一种方法是使用 SparkSQL 内置函数str_to_map

    df.selectExpr("str_to_map(event_list, '~', ':') as map1") \
      .selectExpr(
        "split(map1['PL'],':')[0] as PL", 
        "split(map1['ST'],':')[0] as ST"
    ).show()
    +----------+----------+
    |        PL|        ST|
    +----------+----------+
    |1547497782|1548593509|
    |      null|1548627786|
    |      null|1548637508|
    |1548631949|      null|
    |1548619200|1548635966|
    |1548619583|1548619610|
    |1548619850|1548619850|
    +----------+----------+
    

    注意:您可以将上面的 split 函数替换为 substr 函数(即substr(map1['PL'],1,10)),以防您正好需要前 10 个字符。

    【讨论】:

    • 感谢@jxc,非常快速且有用的方法!这仅选择 PL 和 ST 列,如果我还需要保留其他列怎么办?
    • @DanielG,other columns 是什么意思?你能详细说明并添加预期的结果吗?基本上,在 str_to_map 之后,它是一个 Map 列,您只需要对该 Map 进行一些数据操作。
    • 是的,我的意思是如果我们在 str_to_map 之后的数据框中有 col1、col2 和 event_list (我在我的问题中只提供了 event_list col),我们只有 PL 和 ST 也就是“地图列”而不是 col1 和二氧化碳
    • @DanielG,只需将它们添加到列表中,例如:.selectExpr("col1", "col2", "split(map1['PL'],':')[0] as PL", "split(map1['ST'],':')[0] as ST")
    【解决方案2】:

    尝试使用substring_index 和子字符串的组合

    df.select(
     substring(
       substring_index(df['event_list'], 'PL:', -1), # Get the string starting from 'PL:'
      3, 10).as('PL')) # Skip the first 3 letters and take 10 chars
    

    【讨论】:

      【解决方案3】:

      另一种方法是使用regexp_extract,类似

      val result = df.withColumn("PL", regexp_extract(col("event_list"),"PL\\:(.{0,10})\\:",1))
                     .withColumn("ST", regexp_extract(col("event_list"),"ST\\:(.{0,10})\\:",1))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-04
        • 1970-01-01
        相关资源
        最近更新 更多