У меня есть два DataFrames df_data
и df_node_labels
:
df_data =
nodeId field1
1 abc
2 def
3 fed
4 kfl
df_node_labels =
srcId srcLabel dstId dstLabel
1 AAA 2 BBB
2 BBB 4 FFF
4 FFF 3 CCC
Хочу добавить столбец label
в df_data
. Значения label
следует брать из srcLabel
и dstLabel
:
Вот как я пытался получить информацию о этикетке:
var df = df_data.join(df_node_labels.select("srcId","srcLabel"),col("nodeId")===col("srcId"),"left")
df = df.join(df_node_labels.select("dstId","dstLabel"),col("nodeId")===col("dstId"),"left")
Однако это создает два столбца srcLabel
и dstLabel
в df
, в то время как я хочу получить только один столбец label
.
Это ожидаемый результат:
df =
nodeId field1 label
1 abc AAA
2 def BBB
3 fed CCC
4 kfl FFF
Обновлять:
Я могу сделать это так, но, на мой взгляд, это долгий путь, чтобы сделать простую вещь:
df = df.withColumn("label", when(col("srcLabel") =!= "", col("srcLabel")).otherwise(col("dstLabel"))).drop("srcLabel").drop("dstLabel")
Вы можете создать уникальные данные из df_node_labels
как finalDF
ниже и выполнить операцию join
, которая даст ожидаемый результат.
val finalDF = df_node_labels.select($"srcId".as("nodeId"), $"srcLabel".as("label"))
.union(
df_node_labels.select($"dstId".as("nodeId"), $"dstLabel".as("label"))
).dropDuplicates()
df_data.join(finalDF, Seq("nodeId"), "left")
.show(false)
Выход:
+------+------+-----+
|nodeId|field1|label|
+------+------+-----+
|1 |abc |AAA |
|2 |def |BBB |
|3 |fed |CCC |
|4 |kfl |FFF |
+------+------+-----+
Надеюсь, это вам помогло!
@MichelLemay: Что ты имеешь в виду? Проблема заключалась в том, что nodeId
не всегда принадлежит к srcId
, и его также следует искать в столбце dstId
.
Я заметил, что у вас есть (srcId, srcLabel) и (dstId, dstLabel) с возможным разделением nodeId между srcId и dstId. Следовательно, объединение и удаление дубликатов, как показано в ответе, может вызвать проблемы, если у вас есть разные метки для одного и того же nodeId.
@MichelLemay: Но srcLabel
всегда соответствует dstLabel
, если srcId
совпадает с dstId
.
@ScalaBoy да, но структура данных позволяет иначе, и это, вероятно, плохой дизайн ИМХО. Что делать, если у вас есть другие метаданные вершин (узлов)? Определенно может стать проблемой поддерживать синхронизацию в развивающейся большой таблице данных.
Интересно, что фрейм данных меток узлов предполагает, что он может иметь разные метки, если узел - это
src
илиdst
. В противном случае такая структура не имеет смысла.