#python #apache-spark #pyspark #apache-spark-sql
#python #apache-spark #pyspark #apache-spark-sql
Вопрос:
Может ли кто-нибудь помочь мне понять, почему тип карты в pyspark может содержать дубликаты ключей?
Примером может быть:
# generate a sample dataframe
# the `field` column is an array of struct with value a and value b
# the goal is to create a map from a -> b
df = spark.createDataFrame([{
'field': [Row(a=1, b=2), Row(a=1, b=3)],
}])
# above code would generate a dataframe like this
----------------
| field|
----------------
|[[1, 2], [1, 3]]|
----------------
# with schema
root
|-- field: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- a: long (nullable = true)
| | |-- b: long (nullable = true)
Затем я применил map_from_entries
этот фрейм данных, пытаясь собрать уникальные a->b
пары. Я ожидал, что карта будет содержать уникальные ключи, то есть {1 -> 3}
в данном случае. Тем не менее, я получаю {1 -> 2, 1 -> 3} перед сбором. Это противоречит общей идее map
типа.
import pyspark.sql.functions as F
df.select(F.map_from_entries("field"))
# the result is
-----------------------
|map_from_entries(field)|
-----------------------
| [1 -> 2, 1 -> 3]|
-----------------------
Я также попытался применить F.map_keys()
к этому полю и получил [1, 1]
в результате. Однако, когда я собираю этот фрейм данных, я смог получить результат без дубликатов ключей:
df.select(F.map_from_entries("field")).collect()
# result
[Row(map_from_entries(field)={1: 3})]
Это вызывает некоторое неожиданное поведение в моей работе spark, и я был бы очень признателен, если бы кто-нибудь помог мне понять, почему pyspark ведет себя таким образом. Это ошибка или по замыслу?
Комментарии:
1. пожалуйста, вставьте пример кода для создания df с полем столбца, это поможет нам понять и предоставить решение более структурированным способом . Также, если код находится в pyspark, можете ли вы попробовать использовать функцию create_map .
2. @AdityaVikramSingh привет, Адитья, спасибо за ответ. я обновил описание фрагментом кода для генерации фрейма данных.
Ответ №1:
Это восходит к реализации карт в Scala: https://www.scala-lang.org/api/2.12.2/scala/collection/immutable/List.html#toMap[T,U]:scala.collection.Map[T,U]
Дубликаты ключей будут перезаписаны более поздними ключами: если это неупорядоченная коллекция, какой ключ находится в результирующей карте, не определено
Поэтому карта 1-> 3 перезаписывает 1-> 2. Это разработанное поведение, а не ошибка.
Комментарии:
1. спасибо за ссылку. я понимаю, почему 1-> 3 сохраняется при сборе результата. мой вопрос заключался в том, почему оба ключа хранятся перед сбором.
2. Я предполагаю, что это ошибка в Spark 2.4. В Spark 3.0 я получаю сообщение об ошибке при вызове df.select:
Duplicate map key 1 was found, please check the input data. If you want to remove the duplicated keys, you can set spark.sql.mapKeyDedupPolicy to LAST_WIN so that the key inserted at last takes precedence.