Je voudrais effectuer une jointure à gauche entre deux dataframes, mais les colonnes ne correspondent pas de manière identique. La colonne de jointure dans le premier dataframe a un suffixe supplémentaire par rapport au second dataframe.
from pyspark import SparkContext
import pyspark.sql.functions as f
sc = SparkContext()
df1 = sc.parallelize([
['AB-101-1', 'el1', 1.5],
['ABC-1020-1', 'el2', 1.3],
['AC-1030-1', 'el3', 8.5]
]).toDF(('id1', 'el', 'v1'))
df2 = sc.parallelize([
['AB-101', 3],
['ABC-1020', 4]
]).toDF(('id2', 'v2'))
Le dataframe que je voudrais obtenir à la suite de la jointure gauche est:
df_join = sc.parallelize([
['AB-101-1', 'el1', 1.5, 'AB-101', 3],
['ABC-1020-1', 'el2', 1.3, 'ABC-1020', 4],
['AC-103-1', 'el3', 8.5, None, None]
]).toDF(('id1', 'el', 'v1', 'id2', 'v2'))
Je serais ravi d'utiliser pyspark.sql.substring
pour prendre "tous sauf les 2 derniers caractères", ou d'utiliser quelque chose comme pyspark.sql.like
, mais je n'arrive pas à comprendre comment faire fonctionner l'un ou l'autre correctement dans le joindre.
2 réponses
Cette solution utilise split
pour déconstruire le id1
d'origine, puis concat
pour reconstruire le id2
plus court.
df1 = (
df1
.withColumn('id1_els', f.split('id1','-'))
.withColumn('id2',
f.concat(f.col('id1_els').getItem(0)
, f.lit('-')
, f.col('id1_els').getItem(1)))
)
df_join = df1.join(df2, 'id2', 'left').show()
Mais je préfère utiliser une solution avec substring
ou contains
, car cela dépend fortement de la forme spécifique de mon champ ID.
Dans votre cas spécifique, regexp_extract
est probablement votre meilleure option, mais dans le cas général, vous pouvez utiliser:
df_join = df1.join(df2, df2.id2.contains(df1.id1), how='left')
Questions connexes
De nouvelles questions
pyspark
L'API Spark Python (PySpark) expose le modèle de programmation apache-spark à Python.