Как исправить исключение «Литералы типа« E »в настоящее время не поддерживаются» при применении regex_replace к фрейму данных в Scala? - PullRequest
0 голосов
/ 25 августа 2018

У меня есть фрейм данных, созданный из чтения таблицы RDBMS, как показано ниже:

val dataDF = spark.read.format("jdbc").option("url", connectionUrl)
                                                .option("dbtable", s"(${query}) as year2017")
                                                .option("user", devUserName)
                                                .option("password", devPassword)
                                                .option("numPartitions",15)
                                                .load()

Перед тем, как вставить данные в таблицы Hive в HDFS, нас попросили применить шаблон regex_replace к столбцам фрейма данных.которые имеют тип данных String.Вот как я это применил:

val regExpr = dataDF.schema.fields.map { x =>
  if (x.dataType == StringType)
  "regexp_replace(regexp_replace(regexp_replace(regexp_replace(regexp_replace(%s, E'[\\\\n]+', ' ', 'g' ), E'[\\\\r]+', ' ', 'g' ), E'[\\\\t]+', ' ', 'g' ), E'[\\\\cA]+', ' ', 'g' ), E'[\\\\ca]+', ' ', 'g' ) as %s".format(x.name, x.name)
  else
    x.name
}
dataDF.selectExpr(regExpr:_*)

Но когда я выполняю код, он заканчивается следующим исключением:

Exception in thread "main" org.apache.spark.sql.catalyst.parser.ParseException:
Literals of type 'E' are currently not supported.(line 1, pos 88)

== SQL ==
regexp_replace(regexp_replace(regexp_replace(regexp_replace(regexp_replace(period_name, E'[\\n]+', ' ', 'g' ), E'[\\r]+', ' ', 'g' ), E'[\\t]+', ' ', 'g' ), E'[\\cA]+', ' ', 'g' ), E'[\\ca]+', ' ', 'g' ) as period_name
----------------------------------------------------------------------------------------^^^

Я напечатал схему, используя: println (dataDF.schema),Код правильно идентифицирует столбец String, где вы можете увидеть имя столбца: period_name

Schema: StructType(StructField(forecast_id,LongType,true), StructField(period_num,DecimalType(15,0),true), StructField(period_name,StringType,true), StructField(drm_org,StringType,true), StructField(ledger_id,LongType,true), StructField(currency_code,StringType,true)) 

Требуется удалить пробелы в нескольких форматах.Данные в столбцах String могут иметь значения с пробелами в нескольких форматах.

1,             b,c,   d,

e,Ωåf

Есть несколько пробелов, пробел, значение после новой строки, удаление специальных символов, если они есть, и т. Д.,Приведенную выше строку следует преобразовать в: 1, b, c, d, e, f

Таблица чтения присутствует в базе данных postgres.Я пытался понять, почему E вызывает исключение, но я не могу понять.Может кто-нибудь сообщить мне, как я могу исправить это исключение?

1 Ответ

0 голосов
/ 25 августа 2018

В целях тестирования я создал фрейм данных с предоставленной строкой со специальными символами в столбце col3 как

+----+----+--------------------------------------------------------------------+
|col1|col2|col3                                                                |
+----+----+--------------------------------------------------------------------+
|a   |1   |1,          -   b,c,   d,
                 |
                 |e,Ωåf|
+----+----+--------------------------------------------------------------------+

затем, как предлагается в комментариях к , выберите столбцы со строковым типом и используйте foldleft и withColumn и используйте regexp_replace внутри withColumn , вы можете сделать следующее

//getting column names which are string type
val stringColumns = df.schema.fields.filter(_.dataType == StringType).map(_.name)
//applying regex to replace all characters except digits, characters (a to z and A to Z) and commas
import org.apache.spark.sql.functions._
val finaldf = stringColumns.foldLeft(df){(tempdf, colName) => tempdf.withColumn(colName, regexp_replace(col(colName), "[ ](?=[ ])|[^,A-Za-z0-9]+", ""))}

таким образом finaldf будет как

+----+----+-----------+
|col1|col2|col3       |
+----+----+-----------+
|a   |1   |1,b,c,d,e,f|
+----+----+-----------+ 

Вы можете изменить регулярное выражение [ ](?=[ ])|[^,A-Za-z0-9]+ в соответствии с вашими потребностями. Прямо сейчас ,A-Za-z0-9 символы только не удалены

Надеюсь, ответ полезен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...