0

I need to replace values of several columns (many more than those in the example, so I would like to avoid doing multiple left joins) of a dataframe with values from another dataframe (mapping).

Example:

df1 EXAM

id question1 question2 question3
1 12 12 5
2 12 13 6
3 3 7 5

df2 VOTE MAPPING :

id description
3 bad
5 insufficient
6 sufficient
12 very good
13 excellent

Output

id question1 question2 question3
1 very good very good insufficient
2 very good excellent sufficient
3 bad null insufficient

Edit 1: Corrected id for excellent in vote map

1 Answer 1

1

First of all, you can create a reference dataframe:

df3 = df2.select(
    func.create_map(func.col('id'), func.col('desc')).alias('ref')
).groupBy().agg(
    func.collect_list('ref').alias('ref')
).withColumn(
    'ref', func.udf(lambda lst: {k:v for element in lst for k, v in element.items()}, returnType=MapType(StringType(), StringType()))(func.col('ref'))
)
+---------------------------------------------------------------------------+
|ref                                                                        |
+---------------------------------------------------------------------------+
|{3 -> bad, 12 -> good, 5 -> insufficient, 13 -> excellent, 6 -> sufficient}|
+---------------------------------------------------------------------------+

Then you can replace the value in question columns by getting the value in reference with 1 crossJoin:

df4 = df1.crossJoin(df3)\
    .select(
        'id',
        *[func.col('ref').getItem(func.col(col)).alias(col) for col in df1.columns[1:]]
    )
df4.show(10, False)
+---+----+---------+------------+
|id |q1  |q2       |q3          |
+---+----+---------+------------+
|1  |good|good     |insufficient|
|2  |good|excellent|sufficient  |
|3  |bad |null     |insufficient|
+---+----+---------+------------+
Sign up to request clarification or add additional context in comments.

1 Comment

Hi @Jresearcher, can my solution solve your question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.