Отображение значений в (Py) Spark DataFrame

1

В Pandas можно сделать такую операцию:

mapping = {
    'a': 'The letter A',
    'b': 'The letter B',
    'c': 'The third letter'
}

x = pd.Series(['a', 'b', 'a', c']).map(mapping)

и получить что-то вроде

pd.Series([
    'The letter A',
    'The letter B',
    'The letter A',
    'The third letter'
])

Наивно, я могу добиться этого в PySpark DataFrame с чем-то вроде

import pyspark.sql.functions as F
import pyspark.sql.functions as T

def _map_values_str(value, mapping, default=None):
    """ Apply a mapping, assuming the result is a string """
    return mapping.get(value, default)

map_values_str = F.udf(_map_values_str, T.StringType())

mapping = {
    'a': 'The letter A',
    'b': 'The letter B',
    'c': 'The third letter'
}

data = spark.createDataFrame([('a',), ('b',), ('a',), ('c',)], schema=['letters'])
data = data.withColumn('letters_mapped', map_values_str(F.col('letters'), mapping))

Но UDF, как это, как правило, несколько медленны в больших наборах данных в моем опыте. Есть ли более эффективный способ?

Теги:
pyspark
pyspark-sql

1 ответ

1
Лучший ответ

Я думаю, в этом случае вы могли бы преобразовать dict в DataFrame и просто использовать join:

import pyspark.sql.functions as F

mapping = {
    'a': 'The letter A',
    'b': 'The letter B',
    'c': 'The third letter'
}
# Convert so Spark DataFrame
mapping_df = spark.sparkContext.parallelize([(k,)+(v,) for k,v in mapping.items()]).toDF(['letters','val'])

data = spark.createDataFrame([('a',), ('b',), ('a',), ('c',)], schema=['letters'])
data = data.join(mapping_df.withColumnRenamed('val','letters_mapped'),'letters','left')
data.show()

Выход:

+-------+----------------+
|letters|  letters_mapped|
+-------+----------------+
|      c|The third letter|
|      b|    The letter B|
|      a|    The letter A|
|      a|    The letter A|
+-------+----------------+

Надеюсь это поможет!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню