пропустите разделение, если цифра следует за строкой, чтобы получить массив в python/pyspark

#python #arrays #regex #apache-spark #pyspark

Вопрос:

хотите создать новый столбец на основе строкового столбца, который имеет разделитель (» » ), и пропустить разделение, если за ним следует цифра, и, наконец, удалить «;» в конце, если существует, используя python/pyspark :

Входные :

 "511 520 NA 611;"
"322 GA 620"  
"3 321;"
"334344"
 

ожидаемый результат :

  Column           |  new column
"511 520 NA 611;" | [511,520,NA 611]
"322 GA 620"      | [322,GA 620]
"3 321; "         | [3,321]
"334 344"         | [334,344]
 

пробовать :

 data = data.withColumn(
"newcolumn",
split(col("column"), "s"))
 

но я получаю пустую строку в конце массива, как здесь, и я хочу удалить ее, если она существует

  Column        |  new column
"511 520 NA 611;" | [511,520,NA,611;]
"322 GA 620"      | [322,GA,620]
"3 321;"       | [3,321;]
"334 344"      | [334,344]
 

Ответ №1:

Как уже упоминалось в рекомендациях, вы можете использовать regexp_extract_all вместе с правильным регулярным выражением, как показано ниже:

 from pyspark.sql import functions as F
data = [
  ["511 520 NA 611;"],
  ["322 GA 620"],
  ["3 321;"],
  ["334344"]
]

df = spark.createDataFrame(data, ["value"]) 

df.withColumn("extracted_value", F.expr("regexp_extract_all(value, '(\d )|(\w \s\d )', 0)")).show()

#  --------------- ------------------ 
# |          value|   extracted_value|
#  --------------- ------------------ 
# |511 520 NA 611;|[511, 520, NA 611]|
# |     322 GA 620|     [322, GA 620]|
# |         3 321;|          [3, 321]|
# |         334344|          [334344]|
#  --------------- ------------------ 
 

Ответ №2:

Вы можете использовать regexp_replace, чтобы сначала заменить «;» в конце строки, а затем выполнить разделение. Регулярное выражение «;$» указывает, что строка заканчивается на «;».

 from pyspark.sql import SparkSession
from pyspark.sql.functions import split, col, regexp_replace

spark = SparkSession.builder.getOrCreate()

data = [
    ("511 520 NA 611;",),
    ("322 GA 620",),
    ("3 321;",),
    ("334 344",)
]

df = spark.createDataFrame(data, ['column'])
df = df.withColumn("newcolumn", split(regexp_replace(col("column"), ';


Комментарии:

1. это работает, чтобы справиться с ";" в конце, но все равно не пропускать разделение, если за цифрой следует, как я объясняю в ожидаемом выводе

2. Только подумай о более глупом способе. Сначала используйте функцию regexp_extract_all для извлечения всех специальных строк, затем выполните разделение на остальные строки и, наконец, объедините извлеченные специальные строки с результатом разделения. Но это не может гарантировать порядок.

, ''), "\s"))
df.show(truncate=False)

Комментарии:

1. это работает, чтобы справиться с «;» в конце, но все равно не пропускать разделение, если за цифрой следует, как я объясняю в ожидаемом выводе

2. Только подумай о более глупом способе. Сначала используйте функцию regexp_extract_all для извлечения всех специальных строк, затем выполните разделение на остальные строки и, наконец, объедините извлеченные специальные строки с результатом разделения. Но это не может гарантировать порядок.