Самый быстрый способ получить вход в Java?

Самое чистое решение - передать дополнительные аргументы с помощью закрытия:

def make_topic_word(topic_words):
     return udf(lambda c: label_maker_topic(c, topic_words))

df = sc.parallelize([(["union"], )]).toDF(["tokens"])

(df.withColumn("topics", make_topic_word(keyword_list)(col("tokens")))
    .show())

Это не требует никаких изменений в keyword_list или функции, которую вы обертываете с помощью UDF. Вы также можете использовать этот метод для передачи произвольного объекта. Это может быть использовано для передачи, например, списка sets для эффективных поисков.

Если вы хотите использовать свой текущий UDF и передать topic_words прямо, вам придется преобразовать его в литерал столбца first:

from pyspark.sql.functions import array, lit

ks_lit = array(*[array(*[lit(k) for k in ks]) for ks in keyword_list])
df.withColumn("ad", topicWord(col("tokens"), ks_lit)).show()

В зависимости от ваших данных и требований могут быть альтернативные, более эффективные решения, которые не требуют UDF (взорвать + агрегат + сбой) или поисковые запросы (хеширование + векторные операции).

27
задан Subhrajyoti Majumder 21 December 2012 в 10:57
поделиться

2 ответа

Любые причины, по которым вы не просто используете:

int sign = (int) Math.signum(a); //1 cast for floating-points, 2 for Integer types

Кроме того, большинство реализаций Number имеют метод signum, принимающий примитив этого типа и возвращающий int, так что вы можете избежать приведения для дополнительной производительности.

int sign1 = Integer.signum(12); //no casting
int sign2 = Long.signum(-24l); //no casting

Он вернет +1 / 0 / -1 и был оптимизирован для обеспечения хорошей производительности.

Для справки, вы можете взглянуть на реализацию в openJDK . Соответствующие биты:

public static float signum(float f) {
    return (f == 0.0f || isNaN(f)) ? f : copySign(1.0f, f);
}

public static boolean isNaN(float f) {
    return (f != f);
}

public static float copySign(float magnitude, float sign) {
    return rawCopySign(magnitude, (isNaN(sign) ? 1.0f : sign));
}

public static float rawCopySign(float magnitude, float sign) {
    return Float.intBitsToFloat((Float.floatToRawIntBits(sign)
            & (FloatConsts.SIGN_BIT_MASK))
            | (Float.floatToRawIntBits(magnitude)
            & (FloatConsts.EXP_BIT_MASK
            | FloatConsts.SIGNIF_BIT_MASK)));
}

static class FloatConsts {
    public static final int SIGN_BIT_MASK = -2147483648;
    public static final int EXP_BIT_MASK = 2139095040;
    public static final int SIGNIF_BIT_MASK = 8388607;
}
69
ответ дан HopefullyHelpful 21 December 2012 в 10:57
поделиться

Вы должны только стараться использовать сложную для чтения / понимания оптимизацию, если она абсолютно необходима.

Проблема с

int sign = Math.signum(a);

может заключаться в том, что он возвращает 0, если 0.0 == a

Но вы должны полагаться на существующие библиотечные функции, когда это возможно, чтобы ваш код был легко читаемым / понять.

Если вы хотите 1 для 0.0 == a, что об этом:

int sign = (0>a)?-1:1;
5
ответ дан MrSmith42 21 December 2012 в 10:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: