web-dev-qa-db-fra.com

PySpark et exemple de jointure de diffusion

J'utilise Spark 1.3

# Read from text file, parse it and then do some basic filtering to get   data1
data1.registerTempTable('data1')

# Read from text file, parse it and then do some basic filtering to get data1
data2.registerTempTable('data2')

# Perform join
data_joined = data1.join(data2, data1.id == data2.id);

Mes données sont assez biaisées et data2 (quelques Ko) << data1 (10s de Go) et les performances sont assez mauvaises. Je lisais sur la jointure de diffusion, mais je ne sais pas comment je peux faire la même chose en utilisant Python.

16
user3803714

Spark 1.3 ne prend pas en charge les jointures de diffusion à l'aide de DataFrame. Dans Spark> = 1.5.0, vous pouvez utiliser la fonction broadcast pour appliquer des jointures de diffusion:

from pyspark.sql.functions import broadcast

data1.join(broadcast(data2), data1.id == data2.id)

Pour les anciennes versions, la seule option est de convertir en RDD et d'appliquer la même logique que dans d'autres langues. À peu près quelque chose comme ça:

from pyspark.sql import Row
from pyspark.sql.types import StructType

# Create a dictionary where keys are join keys
# and values are lists of rows
data2_bd = sc.broadcast(
    data2.map(lambda r: (r.id, r)).groupByKey().collectAsMap())


# Define a new row with fields from both DFs
output_row = Row(*data1.columns + data2.columns)

# And an output schema
output_schema = StructType(data1.schema.fields + data2.schema.fields)

# Given row x, extract a list of corresponding rows from broadcast
# and output a list of merged rows
def gen_rows(x):
    return [output_row(*x + y) for y in data2_bd.value.get(x.id, [])]

# flatMap and create a new data frame
joined = data1.rdd.flatMap(lambda row: gen_rows(row)).toDF(output_schema)
33
zero323