Как заменить пробел запятой в Spark (с помощью Scala)?

У меня есть такой файл журнала. Я хочу создать DataFrame в Scala.

2015-05-13T23:39:43.945958Z my-loadbalancer 192.168.131.39:2817 10.0.0.1:80 0.000086 0.001048 0.001337 200 200 0 57 "GET https://www.example.com:443/ HTTP/1.1" "curl/7.38.0" DHE-RSA-AES128-SHA TLSv1.2

Я хочу заменить все пробелы запятыми, чтобы использовать spark.sql, но не могу этого сделать.

Вот все, что я пробовал:

  1. Сначала попытался импортировать его как текстовый файл, чтобы увидеть, есть ли метод replaceAll.
  2. Пробовал разбивать по пространству.

Какие-либо предложения. Я просмотрел документацию, и там нет упоминания о функции замены, как в Pandas.


person San    schedule 26.11.2018    source источник
comment
Возможный дубликат как использовать Regexp_replace в spark   -  person 10465355    schedule 26.11.2018


Ответы (3)


Вы можете просто сказать spark, что ваш разделитель — это пробел, например:

val df = spark.read.option("delimiter", " ").csv("path/to/file")
person Oli    schedule 27.11.2018

Поскольку у вас еще нет типизированных столбцов, я бы начал как RDD, разделил текст с помощью карты, а затем преобразовал в Dataframe со схемой. Грубо:

val rdd = sc.textFile({logline path}).map(line=>line.split("\\s+"))

Затем вам нужно превратить свой RDD (где каждая запись представляет собой массив токенов) в Dataframe. Наиболее надежным способом было бы сопоставить ваши массивы с объектами Row, поскольку RDD[Row] лежит в основе фрейма данных.

Более простой способ встать и пойти был бы

spark.createDataFrame(rdd).toDF("datetime", "host", "ip", ...)
person benlaird    schedule 26.11.2018
comment
Почти точно. Спасибо. - person San; 27.11.2018
comment
Он также заменяет пробел внутри кавычек. Ищем способ преодолеть это. - person San; 27.11.2018
comment
Теперь, когда я думаю об этом, кадры данных Spark имеют считыватель CSV, вероятно, имеет смысл просто использовать это - person benlaird; 27.11.2018
comment
Читатель Scala CSV: spark.apache.org/docs/2.1.0/api/scala/*):org.apache.spark.sql.DataFrame - person benlaird; 27.11.2018
comment
Я хочу использовать его, но мой набор данных представляет собой группу массивов, я имею в виду, что каждая строка представляет собой массив, как показано в приведенном выше журнале. Поэтому я хочу разделить все на основе пространства, дать имена столбцам, а затем выполнить SQL. - person San; 27.11.2018
comment
Большое спасибо @benlaird, кажется, я понял. - person San; 27.11.2018

Если вы просто хотите разделить пространство и сохранить строку в двойных кавычках, вы можете использовать библиотеку apache.commons.csv.

import org.apache.commons.csv.CSVParser._
val str = """2015-05-13T23:39:43.945958Z my-loadbalancer 192.168.131.39:2817 10.0.0.1:80 0.000086 0.001048 0.001337 200 200 0 57 "GET https://www.example.com:443/ HTTP/1.1" "curl/7.38.0" DHE-RSA-AES128-SHA TLSv1.2"""
val http = csv.CSVParser.parse(str,CSVFormat.newFormat(' ').withQuote('"')).getRecords.get(0).get(11)
val curl = csv.CSVParser.parse(str,CSVFormat.newFormat(' ').withQuote('"')).getRecords.get(0).get(12)
println(http)
println(curl)

Полученные результаты:

GET https://www.example.com:443/ HTTP/1.1
curl/7.38.0
person stack0114106    schedule 27.11.2018