如何将 2 个不同的数据帧组合在一起?

How to combine 2 different dataframes together?

我有 2 个 DataFrame:

用户(~29.000.000 个条目)

|-- userId: string (nullable = true)

展示次数(~1000 个条目)

|-- modules: array (nullable = true)
|    |-- element: struct (containsNull = true)
|    |    |-- content: array (nullable = true)
|    |    |    |-- element: string (containsNull = true)
|    |    |-- id: string (nullable = true)

我想遍历所有用户,并从这 ~1000 个条目中为每个用户附加 1 个印象。所以实际上在每个 ~1000th User 中,Impression 将是相同的,然后 Impressions 上的循环将从头开始,并为接下来的 ~1000 个用户分配相同的 ~1000 impression。 最后我想要一个包含组合数据的 DataFrame 。 Users 数据框也可以通过添加 Impressions 的列来重复使用,或者新创建的数据框也可以作为结果。

你有什么想法,哪个是一个好的解决方案?

想法草图:

  • 通过

    向两个数据帧UsersImpressions添加单调递增的id
    val indexedUsersDF = usersDf.withColumn("index", monotonicallyIncreasingId) 
    val indexedImpressionsDF = impressionsDf.withColumn("index", monotonicallyIncreasingId) 
    

    (参见

  • 通过 count 确定 Impressions 中的行数并存储为 int,例如

    val numberOfImpressions = ... 
    
  • 将 UDF 应用于 indexedUsersDF 中的 index 列,计算单独列中的模(例如 moduloIndex)

    val moduloIndexedUsersDF = indexedUsersDF.select(...)
    
  • 加入 moduloIndexedUsersDFindexedImperessionsDF
    moduloIndexedUsersDF("moduloIndex")===indexedImpressions("index")
    

我要做的是使用向两个数据帧添加单调递增 ID 的老技巧,然后在 LARGER 数据帧(用户)上创建一个新列,其中包含每行 ID 的模数和较小数据帧的大小.

此新列随后会针对 Impressions 数据框中的项目提供滚动匹配键。

这是一个最小的例子(经过测试),可以让您了解这个想法。显然,如果您有 1000 次展示要加入,这将有效:

var users = Seq("user1", "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9").toDF("users")
var impressions = Seq("a", "b", "c").toDF("impressions").withColumn("id", monotonically_increasing_id())

var cnt = impressions.count

users=users.withColumn("id", monotonically_increasing_id())
       .withColumn("mod", $"id" mod cnt)
       .join(impressions, $"mod"===impressions("id"))
       .drop("mod")

users.show


+-----+---+-----------+---+
|users| id|impressions| id| 
+-----+---+-----------+---+ 
|user1|  0|          a| 0| 
|user2|  1|          b| 1| 
|user3|  2|          c| 2| 
|user4|  3|          a| 0| 
|user5|  4|          b| 1| 
|user6|  5|          c| 2| 
|user7|  6|          a| 0| 
|user8|  7|          b| 1| 
|user9|  8|          c| 2| 
+-----+---+-----------+---+