Как изменить все значения столбца dataframe в Spark [duplicate]

== проверяет ссылки на объекты, .equals() проверяет строковые значения.

Иногда кажется, что == сравнивает значения, потому что Java делает некоторые закулисные вещи, чтобы убедиться, что одинаковые строки в строке являются одним и тем же объектом.

Для Например:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Но будьте осторожны с нулями!

== обрабатывает строки null в порядке, но вызов .equals() из пустой строки приведет к исключению:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Итак, если вы знаете, что fooString1 может но не менее очевидно, что он проверяет значение null (из Java 7):

System.out.print(Objects.equals(fooString1, "bar"));
3
задан user6910411 9 October 2017 в 17:21
поделиться

2 ответа

Здесь нет гнездования, поэтому нет необходимости в otherwise. Все, что вам нужно, заковано в цепочку when:

import spark.implicits._

when($"tc" isin ("a", "b"), "Y")
  .when($"tc" === "a" && $"amt" >= 0, "N")

ELSE NULL неявно, поэтому вы можете полностью его опустить.

Используемый вами шаблон более подходит для folding над структурой данных:

val cases = Seq(
  ($"tc" isin ("a", "b"), "Y"),
  ($"tc" === "a" && $"amt" >= 0, "N")
)

, где when - otherwise, естественно, следует за шаблоном рекурсии, а null предоставляет базовый случай.

cases.foldLeft(lit(null)) {
  case (acc, (expr, value)) => when(expr, value).otherwise(acc)
}

Обратите внимание, что невозможно достичь результата «N» с этой цепочкой состояний. Если tc равно «a», он будет захвачен первым предложением. Если это не так, он не удовлетворит оба предиката и по умолчанию NULL. Вы должны:

when($"tc" === "a" && $"amt" >= 0, "N")
 .when($"tc" isin ("a", "b"), "Y")
9
ответ дан user6910411 16 August 2018 в 02:16
поделиться

Для более сложной логики я предпочитаю использовать UDF для лучшей читаемости:

val selectCase = udf((tc: String, amt: String) =>
  if (Seq("a", "b").contains(tc)) "Y"
  else if (tc == "a" && amt.toInt <= 0) "N"
  else null
)


dataset1.withColumn("REASON", selectCase(col("tc"), col("amt")))
  .show
0
ответ дан Raphael Roth 16 August 2018 в 02:16
поделиться
Другие вопросы по тегам:

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