Преобразование каждого значения фрейма данных

#scala #apache-spark #dataframe #mapping #rdd

#scala #apache-spark #фрейм данных #сопоставление #rdd

Вопрос:

Мне нужно изменить значения каждого столбца фрейма данных, чтобы все они были заключены в двойные кавычки после сопоставления, но фрейм данных по-прежнему сохраняет свою первоначальную структуру с заголовками.

Я попытался сопоставить значения, изменив строки на последовательности, но он теряет свои заголовки в выходном фрейме данных.

С помощью этого считывания в качестве входного фрейма данных:

 |prodid|name   |city|
 ------ ------- ---- 
|1     |Harshit|VNS |
|2     |Mohit  |BLR |
|2     |Mohit  |RAO |
|2     |Mohit  |BTR |
|3     |Rohit  |BOM |
|4     |Shobhit|KLK |
  

Я попробовал следующий код.

 val columns = df.columns
df.map{ row => 
           row.toSeq.map{col => """ col """ }
    }.toDF(columns:_*)
  

Но он выдает ошибку, указывающую, что в сопоставленном фрейме данных есть только 1 заголовок, т.е. Значение.
Это фактический результат (если я удалю «.df (столбцы: _ *)»):

 |               value|
 -------------------- 
|["1", "Harshit", ...|
|["2", "Mohit", "B...|
|["2", "Mohit", "R...|
|["2", "Mohit", "B...|
|["3", "Rohit", "B...|
|["4", "Shobhit", ...|
 -------------------- 
  

И мой ожидаемый результат выглядит примерно так:

 |prodid|name     |city  |
 ------ --------- ------ 
|"1"   |"Harshit"|"VNS" |
|"2"   |"Mohit"  |"BLR" |
|"2"   |"Mohit"  |"RAO" |
|"2"   |"Mohit"  |"BTR" |
|"3"   |"Rohit"  |"BOM" |
|"4"   |"Shobhit"|"KLK" |
  

Примечание: в этом примере всего 3 заголовка, но в моих исходных данных много заголовков, поэтому ввод каждого из них вручную невозможен в случае изменения заголовка файла. Как мне получить это измененное значение фрейма данных из этого?

Редактировать: если мне нужны кавычки для всех значений, кроме целых чисел. Итак, результат выглядит примерно так:

 |prodid|name     |city  |
 ------ --------- ------ 
|1     |"Harshit"|"VNS" |
|2     |"Mohit"  |"BLR" |
|2     |"Mohit"  |"RAO" |
|2     |"Mohit"  |"BTR" |
|3     |"Rohit"  |"BOM" |
|4     |"Shobhit"|"KLK" |
  

Ответ №1:

Может быть проще использовать select вместо:

 val df = Seq((1, "Harshit", "VNS"), (2, "Mohit", "BLR"))
  .toDF("prodid", "name", "city")

df.select(df.schema.fields.map {
  case StructField(name, IntegerType, _, _) => col(name)
  case StructField(name, _, _, _) => format_string(""%s"", col(name)) as name
}:_*).show()
  

Вывод:

  ------ --------- ----- 
|prodid|     name| city|
 ------ --------- ----- 
|     1|"Harshit"|"VNS"|
|     2|  "Mohit"|"BLR"|
 ------ --------- ----- 
  

Обратите внимание, что существуют и другие числовые типы, такие как LongType и DoubleType поэтому, возможно, потребуется также обработать их или, альтернативно, просто указать StringType и т. Д.

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

1. Можете ли вы сказать мне, что я должен изменить, если мне нужны кавычки для всех значений, кроме целых чисел?

2. @Sidzler отредактировал ответ, теперь он также обрабатывает целые числа

3. Спасибо (: Очень признателен!