Как обрезать поля при загрузке в датафрейм в спарк? - PullRequest
0 голосов
/ 08 февраля 2019

Мы недавно получили файл для загрузки, файл в формате PSV, однако все поля дополняются дополнительными символами $ ~ $ слева и справа, поэтому весь PSV выглядит следующим образом:

$ ~ $ Field1 $ ~ $ | $ ~ $ Field2 $ ~ $ | $ ~ $ Field3 $ ~ $

$ ~ $ Data1 $ ~ $ | $ ~ $ Data2 $ ~ $ | $~ $ Data3 $ ~ $

$ ~ $ Data4 $ ~ $ | $ ~ $ Data5 $ ~ $ | $ ~ $ Data6 $ ~ $

$ ~ $ Data7 $ ~ $ | $~ $ Data8 $ ~ $ | $ ~ $ Data9 $ ~ $

$ ~ $ Data10 $ ~ $ | $ ~ $ Data11 $ ~ $ | $ ~ $ Data12 $ ~ $ .....

В файле 100 миллионов строк.

Какой лучший способ обрезать эти отступы, чтобы сделать его стандартным PSV?

Спасибо большоеЗдесь приветствуется любое предложение / обмен.

ОБНОВЛЕНИЕ:

Данные получены из SFTP и загружены в Hadoop службой поддержки данных ИТ (Unix Admin), у нас есть доступ только к Hadoopкластер, но если это простая работа для поддержки данных, может быть, я смогу убедить их сделать предварительную обработку.Благодарю.

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019

Использование regexp_replace и foldLeft для обновления всех столбцов.Проверьте это

scala> val df = Seq(("$~$Data1$~$","$~$Data2$~$","$~$Data3$~$"), ("$~$Data4$~$","$~$Data5$~$","$~$Data6$~$"), ("$~$Data7$~$","$~$Data8$~$","$~$Data9$~$"),("$~$Data10$~$","$~$Data11$~$","$~$Data12$~$")).toDF("Field1","field2","field3")
df: org.apache.spark.sql.DataFrame = [Field1: string, field2: string ... 1 more field]

scala> df.show(false)
+------------+------------+------------+
|Field1      |field2      |field3      |
+------------+------------+------------+
|$~$Data1$~$ |$~$Data2$~$ |$~$Data3$~$ |
|$~$Data4$~$ |$~$Data5$~$ |$~$Data6$~$ |
|$~$Data7$~$ |$~$Data8$~$ |$~$Data9$~$ |
|$~$Data10$~$|$~$Data11$~$|$~$Data12$~$|
+------------+------------+------------+


scala> val df2 = df.columns.foldLeft(df) { (acc,x) => acc.withColumn(x,regexp_replace(col(x),"""^\$~\$|\$~\$$""","")) }
df2: org.apache.spark.sql.DataFrame = [Field1: string, field2: string ... 1 more field]

scala> df2.show(false)
+------+------+------+
|Field1|field2|field3|
+------+------+------+
|Data1 |Data2 |Data3 |
|Data4 |Data5 |Data6 |
|Data7 |Data8 |Data9 |
|Data10|Data11|Data12|
+------+------+------+


scala>
0 голосов
/ 11 февраля 2019

tr может быть более быстрым решением.обратите внимание, что вы можете передавать любые строки, поэтому в этом случае я cat загружаю файл на диск, но это также может быть поток файлов из sftp.

~/Desktop/test $ cat data.txt
$~$Field1$~$|$~$Field2$~$|$~$Field3$~$

$~$Data1$~$|$~$Data2$~$|$~$Data3$~$

$~$Data4$~$|$~$Data5$~$|$~$Data6$~$

$~$Data7$~$|$~$Data8$~$|$~$Data9$~$

# the '>' will open a new file for writing

~/Desktop/test $ cat data.txt | tr -d \$~\$ > output.psv

# see the results here
~/Desktop/test $ cat output.psv 
Field1|Field2|Field3

Data1|Data2|Data3

Data4|Data5|Data6

Data7|Data8|Data9

примеры: https://shapeshed.com/unix-tr/#what-is-the-tr-command-in-unix

0 голосов
/ 08 февраля 2019

Вот чистое решение Spark.Могут быть более эффективные решения.

var df = spark.read.option("delimiter", "|").csv(filePath)
val replace = (value: String, find: String, replace: String) => value.replace(find, replace)
val replaceUdf = udf(replace)
df.select(
       df.columns.map(c => replaceUdf(col(c), lit("$~$"), lit("")).alias(c)): _*)
  .show

Обновление: Вы не можете использовать $~$ в качестве опции quote или использовать $~$|$~$ в качестве delimiter в 2.3.0, поскольку эти опции принимают только одинхарактер.

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