在pyspark:databricks

b5lpy0ml  于 2021-05-27  发布在  Spark
关注(0)|答案(3)|浏览(469)

我有一个pyspark dataframe列,它的数据如下。

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

我只对后面的前10个数字感兴趣 PL: 以及后面的前10位数 ST: (如果存在)。对于pl split,我使用

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

对于st:由于记录的长度不同,逻辑不起作用,所以我可以使用这个

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

它回来了 ST:1548619856:1548619855 再把第一部分分开。我有1.5米的记录,所以我想知道是否有更好的方法。
这里是预期输出

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

gudnpqoy1#

一种方法是使用sparksql内置函数str \u to \u 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|
+----------+----------+

注:您可以将上述拆分函数替换为substr函数(即。 substr(map1['PL'],1,10) )以防你需要前10个字符。

zvokhttg

zvokhttg2#

另一种方法是使用 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))
bgtovc5b

bgtovc5b3#

试着结合 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

相关问题