PySpark: несколько условий в предложении когда

Я хотел бы изменить значения ячеек столбца данных (Возраст), где в данный момент он пуст, и я сделал бы это только в том случае, если другой столбец (Выживший) имеет значение 0 для соответствующей строки, где он пуст для возраста. Если в столбце "Выживший" он равен 1, а в столбце "Возраст" не указан, то я оставлю это значение пустым.

Я пытался использовать && оператор, но это не сработало. Вот мой код:

tdata.withColumn("Age",  when((tdata.Age == "" && tdata.Survived == "0"), mean_age_0).otherwise(tdata.Age)).show()

Любые предложения, как справиться с этим? Благодарю.

Сообщение об ошибке:

SyntaxError: invalid syntax
  File "<ipython-input-33-3e691784411c>", line 1
    tdata.withColumn("Age",  when((tdata.Age == "" && tdata.Survived == "0"), mean_age_0).otherwise(tdata.Age)).show()
                                                    ^

Ответы

Ответ 1

Вы получаете исключение ошибки SyntaxError, потому что у Python нет оператора &&. Он имеет and и &, где последний является правильным выбором для создания булевых выражений на Column (| для логической дизъюнкции и ~ для логического отрицания).

Условие, которое вы создали, также недействительно, поскольку оно не учитывает приоритет оператора. & в Python имеет более высокий приоритет, чем ==, поэтому выражение должно быть заключено в скобки.

(col("Age") == "") & (col("Survived") == "0")
## Column<b'((Age = ) AND (Survived = 0))'>

В стороне примечание when функция эквивалентна выражению case выражение не when. Тем не менее действуют те же правила. Сопряжение:

df.where((col("foo") > 0) & (col("bar") < 0))

Дизъюнкция:

df.where((col("foo") > 0) | (col("bar") < 0))

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

cond1 = col("Age") == "" 
cond2 = col("Survived") == "0"

cond1 & cond2

Ответ 2

должно работать как минимум в pyspark 2.4

tdata = tdata.withColumn("Age",  when((tdata.Age == "") & (tdata.Survived == "0") , "NewValue").otherwise(tdata.Age))

Ответ 3

(&&) или (||) условия могут быть использованы внутри функции когда

val dataDF = Seq(
      (66, "a", "4"), (67, "a", "0"), (70, "b", "4"), (71, "d", "4"
      )).toDF("id", "code", "amt")
dataDF.withColumn("new_column",
       when(col("code") === "a" || col("code") === "d", "A")
      .when(col("code") === "b" && col("amt") === "4", "B")
      .otherwise("A1")).show()

=======================

Output:
+---+----+---+----------+
| id|code|amt|new_column|
+---+----+---+----------+
| 66|   a|  4|         A|
| 67|   a|  0|         A|
| 70|   b|  4|         B|
| 71|   d|  4|         A|
+---+----+---+----------+

Этот фрагмент кода скопирован с сайта sparkbyexamples.com.

Ответ 4

Это должно быть:

$when(((tdata.Age == "" ) & (tdata.Survived == "0")), mean_age_0)