Коллеги, есть намерение написать UDF для Spark на Scala, которая будет осуществлять поиск по заранее созданному из исходного датафрейма бинарному дереву с _интервалами_ значений и (Tuple3=4(a: T,b: T, n: Int), где T - тип данных, допускающий сравнение, a <= b, n - целое положительное число). То есть, в UDF передается значение одного поля X (x: T), затем осуществляется поиск по бинарному дереву с условием x >= a && x < b, возвращается n или 0, если условие не выполняется для x, a, b. Проблема в том, что это нужно делать с произвольным типом данных, который имеет поле X.
Планирую, что проблему можно решить, если создать параметризованный класс, объект-компаньон которого сделает вывод типа из поля исходного датафрейма, передаст коллекцию с уже определенным типом в конструктор, а после этого можно использовать метод класса как UDF на произвольном поле целевого датафрейма. Но я не вижу способа вывести тип данных, кроме как в .collect сделать pattern matсhing по типам полей, где будет описан каждый возможный вариант преобразования, например LongType >= Long ; DecimalType(m,n) => BigDecimal(m,n) и так далее, но опасаюсь, что такой подход совсем неправильный. Посоветуйте, пожалуйста, как это можно сделать, сохранив вывод типа данных в рантайме
Версия Spark 2.4.0, Scala 2.11.12
Раз уж сегодня речь заходила про Frameless,
@zuynew , подскажи, пожалуйста, может там что-то есть/появилось для датафреймов, но я читал, что только для Dataset, датафреймы только на стадии Proof of Concept, потом их выпилили. Самостоятельно переписать на основе найденного пулл-реквеста frameless с поддержкой датафреймов не удается (версия Scala в том пулл-реквесте 2.11.8), хотя кода там не так много. Если кто-то знает, как помочь, пишите в личку, буду благодарен
Сейчас указанная операция делается через bigDF left join smallDF on x >= a and x < b. Есть очевидные недостатки: длительное выполнение, полная сортировка, возможно появление дубликатов, если исходный датафрейм содержит пересечения интервалов. Зато с типами данных полный порядок
Еще один вариант - сделать огромный case when (условие с литералами a, b) then n. Конечно, речь о его аналоге в DataFrame API when()….otherwise(), но его даже не хочется пробовать, потому что может быть генерация десятков тысяч условий, и выполнение все равно будет линейным,или нужно очень извратиться и сделать «деревоподобный» case when then (