2017-10-18 78 views
0

我一直试图添加一个数据帧的结果作为另一个数据帧中的新数组字段基于一个键值。如何添加一个数据帧转换为阵列作为另一个数据帧的一个元素基于一个键值

例如,我有这样的数据帧我们称之为df1

root  
|-- DF_KEY: integer (nullable = false) 
|-- DF_DESC: string (nullable = false) 

+------------+--------------------+ 
|DF_KEY  |  DF_DESC  | 
+------------+--------------------+ 
|  10000|String Desc A  | 
|  10000|String Desc B  | 

而另一数据框df2

root 
|-- DF_KEY: integer (nullable = false) 
|-- COL_A: decimal(20,0) (nullable = true) 
|-- COL_B: decimal(20,0) (nullable = true) 
|-- COL_C: string (nullable = false) 

我想这两个dataframes与df1的结果相结合一个新的数组ARRAY_OF_DF_DESC,这将导致数据框(newDF)具有以下模式。

root 
|-- DF_KEY: integer (nullable = false) 
|-- COL_A: decimal(20,0) (nullable = true) 
|-- COL_B: decimal(20,0) (nullable = true) 
|-- COL_C: string (nullable = false) 
|-- ARRAY_OF_DF_DESC : array (nullable = false) 
| |-- element: string (containsNull = false) 

我试图做一个连接:

val otherRefsArray = df1.select($"DF_KEY", array(df1.columns.map(col): _*) as "ARRAY_OF_DF_DESC ") 

val newDF = df2.join(otherRefsArray, "DF_KEY") 

但这只能加入每个df1行至newDf数据框添加了一个WrappedArray。并且它会为每个DF_DESC返回重复记录。

如果可能,我想通过一个WrappedArray,其中包含与该行相关的所有DF_DESC关联DF_KEY。有谁知道如何用scala做到这一点?

回答

1

您可以使用groupBy()并收集每个密钥的列表。

val otherRefsArray = df1.groupBy($"DF_KEY") 
    .agg(collect_list($"DF_DESC").as("ARRAY_OF_DF_DESC")) 

之后,以与以前相同的方式使用join

+0

这是唯一的选择吗?我在问,因为我有一些与groupBy有关的问题,因为模式中有一些重复。如果没有其他选项,我将解决重复问题并尝试groupBy。 –

+0

@RonniePhelps我会说'groupBy()'与'collect_list'是最简单的解决方案,我不认为你可以避免在'df1'数据框上进行某种分组,因为你有多个相同的键。在这种情况下,不应该有任何重复的问题?或者还有其他专栏涉及这个问题吗? – Shaido

+0

这只是我为简单发布的一个示例,但还有其他属性没有列出在模式中有重复项。 –

相关问题