Форматировать файл csv с созданием столбца в Spark scala

У меня есть файл csv, как показано ниже

Он имеет 6 строк с верхней строкой в ​​​​качестве заголовка, а заголовок читается как «Оценки учащихся». dataframe обрабатывает их как один столбец, теперь я хочу разделить оба столбца с данными. "студент" и "отметки" разделены пробелом.

df.show()    
_______________
##Student Marks##    
---------------    
A   10;20;10;20    
A   20;20;30;10    
B   10;10;10;10    
B   20;20;20;10    
B   30;30;30;20

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

Student | Marks
A       | 30;40;40;30
B       | 60;60;60;40

Я пробовал ниже, но выдает ошибку

df.withColumn("_tmp", split($"Students Marks","\\ ")).select($"_tmp".getItem(0).as("col1"),$"_tmp".getItem(1).as("col2")).drop("_tmp")
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
313
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Три идеи. Первый — прочитать файл, разбить его по пробелам, а затем создать dataFrame:

val df = sqlContext.read
  .format("csv")
  .option("header", "true")
  .option("delimiter", " ")
  .load("your_file.csv")

Второй — прочитать файл в фреймворк данных и разбить его:

df.withColumn("Student", split($"Students Marks"," ").getItem(0))
  .withColumn("Marks", split($"Students Marks"," ").getItem(1))
  .drop("Students Marks")

Последнее - ваше решение. Это должно работать, но когда вы используете выбор, вы не используете $"_tmp", поэтому он должен работать без .drop("_tmp")

df.withColumn("_tmp", split($"Students Marks"," "))
  .select($"_tmp".getItem(0).as("Student"),$"_tmp".getItem(1).as("Marks"))

org.apache.spark.sql.AnalysisException: невозможно разрешить 'value' заданные входные столбцы: [Оценки учащихся];;

Sam 29.05.2019 11:16

Я отредактировал свой ответ, можете ли вы использовать sep вместо delimiter?

Pablo López Gallego 29.05.2019 11:19
val df = spark.read.option("delimiter", " ").option("header", "true").csv("path/to/file") если это не сработает, могу ли я увидеть вашу ошибку?
Pablo López Gallego 29.05.2019 11:23

не ошибка здесь, а во второй строке, она выдает ошибку org.apache.spark.sql.AnalysisException: невозможно разрешить «значение» для заданных входных столбцов: [Оценки учащихся];; .

Sam 29.05.2019 11:30

Я отредактировал свой ответ и изменил «значение» на «Отметки учащихся», попробуйте один из трех новых вариантов.

Pablo López Gallego 29.05.2019 11:32

во время чтения. он принимает их как одно и то же значение. Также знаете ли вы, как добавить оценки для конкретного ученика?

Sam 29.05.2019 11:32

Так? .withColumn("Marks", if (split(col("Students Marks")," ").getItem(0) == lit("A")) split(col("Students Marks")," ").getItem(1) else lit("100;100;100;100"))

Pablo López Gallego 29.05.2019 11:43

df.withColumn("_tmp", split($"Отметки учащихся"," ")) .select($"_tmp".getItem(0).as("Студент"),$"_tmp".getItem(1). ‌​as("Знаки")) - сработало. Спасибо. Теперь позвольте мне посмотреть, как добавить эти числа

Sam 29.05.2019 11:45

Давайте продолжить обсуждение в чате.

Sam 29.05.2019 11:48
Ответ принят как подходящий

Вы можете прочитать файл csv с нужным разделителем и рассчитать результат, как показано ниже.

    val df = spark.read
      .option("header", true)
      .option("delimiter", " ")
      .csv("path to csv")

После того, как вы получите dataframe df

val resultDF = df.withColumn("split", split($"Marks", ";"))
  .withColumn("a", $"split"(0))
  .withColumn("b", $"split"(1))
  .withColumn("c", $"split"(2))
  .withColumn("d", $"split"(3))
  .groupBy("Student")
  .agg(concat_ws(";", array(
     Seq(sum($"a"), sum($"b"), sum($"c"), sum($"d")): _*)
  ).as("Marks"))


resultDF.show(false)

Выход:

+-------+-------------------+
|Student|Marks              |
+-------+-------------------+
|B      |60.0;60.0;60.0;40.0|
|A      |30.0;40.0;40.0;30.0|
+-------+-------------------+

Другие вопросы по теме