Dataframe Join Left Behavior

Мне нужно объединить два кадра данных вместе, чтобы добавить данные столбца, если они есть, и они ведут себя не так, как я ожидал.

ДФА:

# +---+-----+-----+
# | id|d_var|d_val|
# +---+-----+-----+
# |a01|  112| null|
# |a01|  113|    0|
# |a02|  112| null|
# |a02|  113|    0|
# +---+-----+-----+

ДФБ:

# +---+-----+-----+------+-----+
# | id|d_var|d_val|c_type|c_val|
# +---+-----+-----+------+-----+
# |a01|  112| null|   red|    1|
# |a01|  113|    0|   red|    1|
# +---+-----+-----+------+-----+

Вот создание фрейма данных и вызов присоединения, который ведет себя неожиданно:

dfA = spark.createDataFrame(
    [
        ('a01', '112', None),
        ('a01', '113', '0'),
        ('a02', '112', None),
        ('a02', '113', '0')
    ],
    ('id', 'd_var', 'd_val')
)

dfB = spark.createDataFrame(
    [
        ('a01', '112', None, 'red', '1'),
        ('a01', '113', '0', 'red', '1')
    ],
    ('id', 'd_var', 'd_val', 'c_type', 'c_val')
)

static_cols = dfB.columns[:3]
dfA.join(dfB, static_cols, how='left').orderBy('id', 'd_var').show()

Выход:

# +---+-----+-----+------+-----+
# | id|d_var|d_val|c_type|c_val|
# +---+-----+-----+------+-----+
# |a01|  112| null|  null| null|  <-
# |a01|  113|    0|   red|    1|
# |a02|  112| null|  null| null|
# |a02|  113|    0|  null| null|
# +---+-----+-----+------+-----+

Ожидаемый (и желаемый) результат:

# +---+-----+-----+------+-----+
# | id|d_var|d_val|c_type|c_val|
# +---+-----+-----+------+-----+
# |a01|  112| null|   red|    1|  <-
# |a01|  113|    0|   red|    1|
# |a02|  112| null|  null| null|
# |a02|  113|    0|  null| null|
# +---+-----+-----+------+-----+

person Tibberzz    schedule 13.06.2018    source источник
comment
2.3.0 (переполнение стека требует больше символов здесь, чтобы оставить комментарий)   -  person Tibberzz    schedule 13.06.2018
comment
Похоже, проблема с искрой, правильно приравнивающей столбцы null в соединении. Поскольку вы находитесь на 2.3.0, взгляните на этот ответ относительно Column.eqNullSafe в PySpark.   -  person Travis Hegner    schedule 13.06.2018
comment
Вот и все, @TravisHegner, спасибо. Правильно, я пометил это как дубликат.   -  person Tibberzz    schedule 14.06.2018


Ответы (1)


(отправляю мой ответ, если он останется вместе с дополнением @Shaido)

cond = (dfA.id.eqNullSafe(dfB.id) & dfA.d_var.eqNullSafe(dfB.d_var) & dfA.d_val.eqNullSafe(dfB.d_val))
dfA.join(dfB, cond, how='left').select(dfA.id, dfA.d_var, dfA.d_val, dfB.c_type, dfB.c_val).orderBy('id', 'd_var').show()
person Tibberzz    schedule 14.06.2018