У меня есть файл 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")
Три идеи. Первый — прочитать файл, разбить его по пробелам, а затем создать 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"))
Я отредактировал свой ответ, можете ли вы использовать sep
вместо delimiter
?
val df = spark.read.option("delimiter", " ").option("header", "true").csv("path/to/file")
если это не сработает, могу ли я увидеть вашу ошибку?
не ошибка здесь, а во второй строке, она выдает ошибку org.apache.spark.sql.AnalysisException: невозможно разрешить «значение» для заданных входных столбцов: [Оценки учащихся];; .
Я отредактировал свой ответ и изменил «значение» на «Отметки учащихся», попробуйте один из трех новых вариантов.
во время чтения. он принимает их как одно и то же значение. Также знаете ли вы, как добавить оценки для конкретного ученика?
Так? .withColumn("Marks", if (split(col("Students Marks")," ").getItem(0) == lit("A")) split(col("Students Marks")," ").getItem(1) else lit("100;100;100;100"))
df.withColumn("_tmp", split($"Отметки учащихся"," ")) .select($"_tmp".getItem(0).as("Студент"),$"_tmp".getItem(1). as("Знаки")) - сработало. Спасибо. Теперь позвольте мне посмотреть, как добавить эти числа
Давайте продолжить обсуждение в чате.
Вы можете прочитать файл 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|
+-------+-------------------+
org.apache.spark.sql.AnalysisException: невозможно разрешить '
value
' заданные входные столбцы: [Оценки учащихся];;