Как разделить столбец dataframe, который содержит строки - PullRequest
0 голосов
/ 22 сентября 2018

Я использую spark 2.2 и пытаюсь прочитать набор данных из файла tsv, как показано ниже в pyspark:

    student_id subjects result
    "1001" "[physics, chemistry]" "pass"
    "1001" "[biology, math]" "fail"
    "1002" "[economics]" "pass"
    "1002" "[physics, chemistry]" "fail"

И мне нужен следующий вид результата:

    student_id subject result
    "1001" "physics" "pass"
    "1001" "chemistry" "pass"
    "1001" "biology" "fail"
    "1001" "math" "fail"
    "1002" "economics" "pass"
    "1002" "physics" "fail"
    "1002" "chemistry" "fail"

Я сделал следующее, но, похоже, это не работает

    df = spark.read.format("csv").option("header", "true").option("mode", "FAILFAST") \
    .option("inferSchema", "true").option("sep", ' ').load("ds3.tsv")
    df.printSchema()

Я вижу следующий результат, когда я выполняю "printSchema"

   root
    |-- student_id: integer (nullable = true)
    |-- subjects: string (nullable = true)
    |-- result: string (nullable = true)

Когда я делаюто есть используйте функцию разнесения:

    df.withColumn("subject", explode(col("subjects"))).select("student_id", "subject", "result").show(2)

Я получаю следующее исключение:

    AnalysisException: "cannot resolve 'explode(`subjects`)' due to data type mismatch: input to function explode should be array or map type, not string;;\n'Project [student_id#10, subjects#11, results#12, explode(subjects#11) AS subject#30]\n+- AnalysisBarrier\n      +- Relation[student_id#10,subjects#11,result#12] csv\n"

Я где-то читал, что pyspark не поддерживает ArrayType для строк.

Этохорошая идея написать UDF, который обрезал бы символы «[]» с обоих концов значений столбца «subject», затем использовал бы функцию «split» и использование «explode»?

1 Ответ

0 голосов
/ 22 сентября 2018

Второй столбец - String, его можно разделить, а затем «взорвать»:

val df = List(
  ("1001", "[physics, chemistry]", "pass"),
  ("1001", "[biology, math]", "fail"),
  ("1002", "[economics]", "pass"),
  ("1002", "[physics, chemistry]", "fail")
).toDF("student_id", "subjects", "result")

df
  .withColumn("clearedFromLeftBracket", expr("substring(subjects,2,length(subjects))"))
  .withColumn("clearedFromBrackets", expr("substring(clearedFromLeftBracket,1,length(clearedFromLeftBracket)-1)"))
  .withColumn("splitted", split($"clearedFromBrackets", ", "))
  .withColumn("subjectResult", explode($"splitted"))
  .drop("clearedFromLeftBracket", "clearedFromBrackets", "splitted","subjects")

Вывод:

+----------+------+-------------+
|student_id|result|subjectResult|
+----------+------+-------------+
|1001      |pass  |physics      |
|1001      |pass  |chemistry    |
|1001      |fail  |biology      |
|1001      |fail  |math         |
|1002      |pass  |economics    |
|1002      |fail  |physics      |
|1002      |fail  |chemistry    |
+----------+------+-------------+
...