Можно ли сохранить общее состояние между окнами при использовании UDF в BigQuery?

Это вопрос, следующий за моим предыдущим вопросом о возможности эмуляции агрегатных функций (например, в PGSQL) в BigQuery.

Решение, предложенное в предыдущем вопросе, действительно работает для случаев, когда функция, применяемая в каждом окне, не зависит от предыдущего окна - например, вычисление простого среднего и т. Д., Но при вычислении рекурсивных функций, таких как экспоненциальная скользящая средняя, ​​где формула:EMA[i] = price[i]*k + EMA[i-1]×(1−k)

Используя тот же пример из предыдущего вопроса,

CREATE OR REPLACE FUNCTION temp_db.ema_func(arr ARRAY<int64>, window_size int8)
RETURNS int64 LANGUAGE js AS """
    if(arr.length<=window_size){
        // calculate a simple moving average till end of first window
        var SMA = 0;
        for(var i = 0;i < arr.length; i++){
            SMA = SMA + arr[i]
        }
        return SMA/arr.length
    }else{
        // start calculation of EMA where EMA[i-1] is the SMA we calculated for the first window
        // note: hard-coded constant (k) for the sake of simplicity
        // the problem: where do I get EMA[i-1] or prev_EMA from?
        // in this example, we only need the most recent value, but in general case, we would 
        // potentially have to do other calculations with the new value 
        return curr[curr.length-1]*(0.05) + prev_ema*(1−0.05)
    }
""";

select s_id, temp_db.ema_func(ARRAY_AGG(s_price) over (partition by s_id order by s_date rows 40 preceding), 40) as temp_col
from temp_db.s_table;

Сохранение переменной состояния как пользовательского типа в PGSQL очень просто и является частью параметров агрегатной функции. Можно ли имитировать ту же функциональность с помощью BigQuery?

1 ответ

Решение

Я не думаю, что это можно сделать в целом для BigQuery, и я скорее хотел увидеть конкретный случай и посмотреть, возможно ли какое-то разумное решение. Между тем, опять же, рекурсивность и агрегированный UDF - это то, что не поддерживается [надеюсь, пока] в BQ, поэтому вы можете отправить соответствующий запрос (-ы) функции.

Тем временем проверяйте скрипт BQ, но я не думаю, что ваш случай туда подойдет

Другие вопросы по тегам