Генерация текста из DF из имени файла - PullRequest
0 голосов
/ 28 марта 2020

Добрый вечер

У меня есть следующий фрейм данных

val dfInfo = df.select(col("Info"), col("eventLineage.filename")).
      groupBy(col("consistencyInfo"), col("filename")).agg(count(col("filename")))
        .orderBy(col("filename"))
+-----------------------------------------------------------------------
|Info  |filename                                       |count(filename)|
+-----------------------------------------------------------------------
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|1              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|5              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|1              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|5              |
+-----------------------------------------------------------------------

Как мне сгенерировать txt или создать фрейм данных с данными, разделенными именем файла. Другими словами, я хочу создать df / txt с данными из file01 и txt с данными файла file02.

Я бы хотел что-то подобное

file01

+-----------------------------------------------------------------------
|Info  |filename                                       |count(filename)|
+-----------------------------------------------------------------------
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|1              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file01|5              |

file02

+-----------------------------------------------------------------------
|Info  |filename                                       |count(filename)|
+-----------------------------------------------------------------------
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|1              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|2              |
|[1234]|file:/home/serasa.intranet/c81484a/teste/file02|5              |
+-----------------------------------------------------------------------

1 Ответ

0 голосов
/ 28 марта 2020

Если я правильно понимаю, вы пытаетесь создать DataFrame для уникального значения в столбце 'fileName'.

Вы не можете spilt a DataFrame, поэтому вам придется применять преобразование к исходному DataFrame для каждого дочернего DataFrame, который вы хотите создать.

Если вы знаете, что есть только два значения, затем

df1 = dfInfo.filter(col("filename") === "file:/home/serasa.intranet/c81484a/teste/file01" // or endsWith "1"
df1 = dfInfo.filter(col("filename") === "file:/home/serasa.intranet/c81484a/teste/file01" // or endsWith "2"

А если неизвестно, то вы можете написать обобщенную функцию c, как показано ниже:

  //returns Array of [column value as String and DataFrame]
  def generateFrames(df: DataFrame, by: Column): Array[(String, DataFrame)] = {
    val distinctRecords = df.select(by).distinct().cache()
    if (distinctRecords.filter(by.isNull).count() == 0)
      distinctRecords.collect().map(r => (r.get(0).toString, df.filter(by === r.get(0))))
    else
  //If column contains any null value.
      distinctRecords.filter(by.isNotNull).collect().map(r => (r.get(0).toString, df.filter(by === r.get(0)))) :+ ("Null", df.filter(by.isNull))
  }

, поэтому в вашем примере это будет:

generateFrames(dfInfo, col("filename")).foreach(v => {
    println(s"Invoking show on  DF: ${v._1}")
    v._2.show()
  }
  )

Примечание : Если вы собираетесь вызывать действие для каждой отдельной линии DataFrame отдельно, я бы посоветовал вам сначала кэшировать ее.

...