#scala #apache-spark #apache-spark-sql #distinct
Вопрос:
Для одного из этапов очистки данных я хотел бы получить представление о том, как существуют уникальные значения в процентах от общего количества строк, чтобы я мог применить пороговое значение и решить, следует ли полностью удалить этот столбец / функцию. Для этого я придумал эту функцию, как показано ниже:
def uniqueValuesAsPercentage(data: DataFrame) = {
val (rowCount, columnCount) = shape(data)
data.selectExpr(data.head().getValuesMap[Long](data.columns).map(elem => {
val (columnName, uniqueCount) = elem
val percentage = uniqueCount / rowCount * 100
(columnName, uniqueCount, percentage)
}))
}
Но это не удается со следующей ошибкой:
<console>:90: error: type mismatch;
found : scala.collection.immutable.Iterable[(String, Long, Long)]
required: String
data.selectExpr(data.head().getValuesMap[Long](data.columns).map(elem => {
К сожалению, поскольку это находится в записной книжке Apache Zeppelin, мне также не хватает возможностей IDE. У меня есть IntelliJ до конца, но поддержка инструментов больших данных, похоже, недоступна для моей версии IDE. Очень раздражает!
Есть какие-нибудь идеи относительно того, в чем здесь проблема? Я думаю, что я путаюсь с фреймом данных в selectExpr(….). Как видно, я возвращаю кортеж с информацией, которую я вычисляю.
Комментарии:
1.
selectExpr
получает строку, представляющую выражение sql (cast(col_x as string)
), но вы предоставляете ей итерацию кортежей. Смотрите мое предлагаемое решение ниже.
Ответ №1:
Вы можете рассчитать это гораздо более простым способом:
import org.apache.spark.sql.functions.{col, countDistinct, count}
import spark.implicits._
// define a dataframe for example
val data = Seq(("1", "1"), ("1", "2"), ("1", "3"), ("1", "4")).toDF("col_a", "col_b")
data.select(data.columns.map(c => (lit(100) * countDistinct(col(c)) / count(col(c))).alias(c)): _*).show()
// output:
----- -----
|col_a|col_b|
----- -----
| 25.0|100.0|
----- -----
Комментарии:
1. Показать-это хорошо, но есть ли возможность извлечь значения из фрейма данных?
2. @joesan конечно, используйте
collect()
вместоshow()
и назначьте результат в переменную.