我需要使用左反連接來提取所有不匹配的行,但問題是左反連接在選擇列方面不靈活,因為它只允許我從左側選擇列資料框...我還需要從正確的資料框中保留一些列。所以我嘗試了:
cols_to_keep = ['col1_left_df', 'col2_left_df', 'col3_left_df',
'col1_right_df', 'col2_right_df', 'col3_right_df']
non_matches = (
left_df.join(right_df, [left_df.['col1_left_df'] == right_df.['col1_right_df']], how = 'lefouter')
.filter(col('col1_left_df').isNull()) & col('col1_right_df').isNull())
.select(cols_to_keep)
)
這使我可以從左右資料框中選擇列,并且沒有回傳錯誤。但是,由于大小和兩者——實際資料的已知和未知復雜性——我仍在檢查它是否按預期作業(這需要我很長時間)。
我的問題:是否有另一種復制左反連接的方法,可以讓我從左右資料幀中選擇列?
uj5u.com熱心網友回復:
示例輸入:
from pyspark.sql import functions as F
df_left = spark.createDataFrame(
[(1111, 4444),
(2222, 5555),
(None, 6666)],
['left_a', 'left_b'])
df_right = spark.createDataFrame(
[(1111, 7777),
(3333, 8888),
(None, 9999)],
['right_a', 'right_b'])
cols_to_keep = ['left_a', 'left_b', 'right_a', 'right_b']
如果我們進行左反連接,我們會得到以下資料框:
df_left.join(df_right, df_left.left_a == df_right.right_a, 'leftanti').show()
# ------ ------
# |left_a|left_b|
# ------ ------
# | null| 6666|
# | 2222| 5555|
# ------ ------
如果我們使用您的腳本,我們會得到:
df_non_matches = (
df_left
.join(df_right, df_left.left_a == df_right.right_a, how='leftouter')
.filter(F.col('left_a').isNull() & F.col('right_a').isNull())
.select(cols_to_keep)
)
df_non_matches.show()
# ------ ------ ------- -------
# |left_a|left_b|right_a|right_b|
# ------ ------ ------- -------
# | null| 6666| null| null|
# ------ ------ ------- -------
可以看出,你實作的全左外連接演算法并不等同于左反連接。
您可以使用左外連接按自己的方式進行操作,但我認為您不需要過濾條件之一:
df_non_matches = (
df_left
.join(df_right, df_left.left_a == df_right.right_a, how='leftouter')
.filter(F.isnull('right_a'))
.select(cols_to_keep)
)
df_non_matches.show()
# ------ ------ ------- -------
# |left_a|left_b|right_a|right_b|
# ------ ------ ------- -------
# | null| 6666| null| null|
# | 2222| 5555| null| null|
# ------ ------ ------- -------
此外,您可以執行左反連接,但完成后只需從右資料框中添加缺少的空列:
df_non_matches = (
df_left
.join(df_right, df_left.left_a == df_right.right_a, 'leftanti')
.select(*[c if c in df_left.columns else F.lit(None).alias(c) for c in cols_to_keep])
)
df_non_matches.show()
# ------ ------ ------- -------
# |left_a|left_b|right_a|right_b|
# ------ ------ ------- -------
# | null| 6666| null| null|
# | 2222| 5555| null| null|
# ------ ------ ------- -------
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/516144.html
