我想在两个数据帧之间执行左连接,但列不完全相同。第一个数据帧中的连接列相对于第二个数据帧有一个额外的后缀。
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'))
Run Code Online (Sandbox Code Playgroud)
我想通过左连接获得的数据帧是:
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'))
Run Code Online (Sandbox Code Playgroud)
我很乐意使用pyspark.sql.substring
“除最后两个字符之外的所有字符”,或者使用类似的东西pyspark.sql.like
,但我不知道如何使这些中的任何一个在连接内正常工作。
如果id1
&id2
有一些与您在问题中所说明的模式类似的模式,那么我建议采用以下方法。
from pyspark.sql.functions import regexp_extract
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'))
df1 = df1.withColumn("id1_transformed", regexp_extract('id1', '(.*-.*)(-.*)', 1))
df_join = df1.join(df2, df1.id1_transformed==df2.id2, 'left').drop("id1_transformed")
df_join.show()
Run Code Online (Sandbox Code Playgroud)
输出是:
+----------+---+---+--------+----+
| id1| el| v1| id2| v2|
+----------+---+---+--------+----+
|ABC-1020-1|el2|1.3|ABC-1020| 4|
| AB-101-1|el1|1.5| AB-101| 3|
| AC-1030-1|el3|8.5| null|null|
+----------+---+---+--------+----+
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
在您的具体情况下,regexp_extract
可能是您的最佳选择,但在一般情况下您可以使用:
df_join = df1.join(df2, df2.id2.contains(df1.id1), how='left')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11382 次 |
最近记录: |