У меня проблемы с удалением строк из dataframe на основе двух столбцов списка элементов для фильтрации. Например, для этого dataframe:Невозможно создать литерал массива в spark/pyspark
df = spark.createDataFrame([(100, 'A', 304), (200, 'B', 305), (300, 'C', 306)], ['number', 'letter', 'id'])
df.show()
+------+------+---+
|number|letter| id|
+------+------+---+
| 100| A|304|
| 200| B|305|
| 300| C|306|
+------+------+---+
можно легко удалить строки с помощью isin
на одной колонке:
df.where(~col('number').isin([100, 200])).show()
+------+------+---+
|number|letter| id|
+------+------+---+
| 300| C|306|
+------+------+---+
Но когда я пытаюсь удалить их двумя колонками я получаю исключение:
df.where(~array('number', 'letter').isin([(100, 'A'), (200, 'B')])).show()
Py4JJavaError: An error occurred while calling z:org.apache.spark.sql.functions.lit.
: java.lang.RuntimeException: Unsupported literal type class java.util.ArrayList [100, A]
at org.apache.spark.sql.catalyst.expressions.Literal$.apply(literals.scala:57)
at org.apache.spark.sql.functions$.lit(functions.scala:101)
at org.apache.spark.sql.functions.lit(functions.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:237)
at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
at py4j.Gateway.invoke(Gateway.java:280)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:214)
at java.lang.Thread.run(Thread.java:745)
После некоторого расследования я понял, что основной причиной проблемы является создание литералов из непримиримых типов. Я попытался следующий код в pyspark:
lit((100, 'A'))
lit([100, 'A'])
и следующее в Искре лестницу:
lit((100, "A"))
lit(List(100, "A"))
lit(Seq(100, "A"))
lit(Array(100, "A"))
, но не повезло ... Кто-нибудь знает, как создать массив буквальный в свече/pyspark ? Или есть другой способ фильтрации данных на два столбца?