Значение PySpark с запятой не содержит запятую ?? (Попытка привести к ArrayType (StringType ())) - PullRequest
0 голосов
/ 04 сентября 2018

Я использую PySpark v1.6.0, и у меня есть столбец строковых значений (в соответствии с .printSchema), но когда я пытаюсь отфильтровать строки в соответствии со случаями, когда значение столбца начинается с символа «[» или содержит символ "," в обоих случаях говорит о том, что строки, которые я ожидаю оценить как True, по-прежнему ложны ...

Когда я запускаю код:

col_name = "attempt_params_attempt_response_id"
resultDF.select(col_name, resultDF[col_name].like(",")).show(50)

Я получаю:

Picture where column value should be true but is false

Я не понимаю, как это возможно, потому что строковое значение явно содержит запятую, поэтому строка должна возвращать true, а не false.

Точно так же, когда я пытаюсь привести строки к ArrayType(StringType()) (что является моей конечной целью), он также ведет себя так, как будто мои строки не содержат запятой ...

Когда я запускаю код:

from pyspark.sql.types import ArrayType, IntegerType, StringType

col_name = "attempt_params_attempt_response_id"
resultDF.withColumn(col_name, 
                    split(resultDF[col_name], ",\s*")
                    .cast(ArrayType(StringType()))).select(col_name).show(40)

Я получаю результаты:

Multidimensional array as if there was no comma to split on

Интересно, возможно, существует какая-то странная проблема с кодировкой, из-за которой символ , не совпадает с символом, который в данных представляется символом , ... но я действительно не уверен. Любые идеи о том, почему это происходит и как я могу на самом деле заставить актерский состав работать без создания текста многомерного массива?

1 Ответ

0 голосов
/ 04 сентября 2018

В случае, если ваш шаблон неверен. like эквивалентно SQL, как и использование простого регулярного выражения, поэтому , соответствует только литералу ,.

df = spark.createDataFrame([("[0,2,3]", ), (",", )], ("text", ))
df.withColumn("contains_comma", col("text").like(",")).show()
+-------+--------------+
|   text|contains_comma|
+-------+--------------+
|[0,2,3]|         false|
|      ,|          true|
+-------+--------------+

Чтобы получить совпадение, необходимо добавить начальные и конечные символы подстановки:

df.withColumn("contains_comma", col("text").like("%,%")).show()


# +-------+--------------+
# |   text|contains_comma|
# +-------+--------------+
# |[0,2,3]|          true|
# |      ,|          true|
# +-------+--------------+

Во втором случае вообще нет проблем. Поскольку вы разбили на ,, первый элемент будет содержать ведущий [

df.withColumn("contains_comma", split("text", ",\s*")[0]).show()
+-------+--------------+
|   text|contains_comma|
+-------+--------------+
|[0,2,3]|            [0|
|      ,|              |
+-------+--------------+

и последний трейлинг ]. Вы должны удалить их, если вы не хотите, чтобы они выводились, например, используя regexp_replace:

split(regexp_replace("text", "^\[|\]$",  ""), ",")
...