Если вы хотите избежать нескольких обращений к udf (что полезно, особенно если udf является узким местом в вашей работе), вы можете сделать это следующим образом:
val testUDF = udf(test _).asNondeterministic()
В основном вы говорите Spark, что вашфункция не является детерминированной, и теперь Spark гарантирует, что она вызывается только один раз, потому что небезопасно вызывать ее несколько раз (каждый вызов может возвращать разные результаты).
Также следует помнить, что этот прием не бесплатенвыполняя это, вы накладываете некоторые ограничения на оптимизатор, одним из побочных эффектов которого является, например, то, что оптимизатор Spark не проталкивает фильтры через выражения, которые не являются детерминированными, поэтому вы становитесь ответственными за оптимальное расположение фильтров в вашем запросе.