Разделить 1 столбец с длинным текстом на 2 столбца в pyspark: databricks - PullRequest
1 голос
/ 26 мая 2020

У меня есть столбец фрейма данных 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

Меня интересуют только первые 10 цифр после PL: и первые 10 цифр после ST: (если существует). Для разделения PL я использовал

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

для ST: поскольку записи имеют другую длину, что logi c доза не работает, я могу использовать это

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 

Ответы [ 3 ]

3 голосов
/ 26 мая 2020

Один из способов - использовать встроенную функцию Spark SQL 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 символов.

2 голосов
/ 26 мая 2020

попробуйте с комбинацией 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
1 голос
/ 26 мая 2020

Другой способ - использовать 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))
...