我有2个DataFrames:
用户(~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印象。因此,实际上在每个~1000个用户中Impression将是相同的,然后Impressions上的循环将从头开始并为下一个~1000个用户分配相同的~1000个印象。 最后,我想要一个包含组合数据的DataFrame。此外,用户数据框可以通过添加展示次数的列来重复使用,或者新创建的数据框也可以作为结果使用。
你有任何想法,这将是一个很好的解决方案吗?
答案 0 :(得分:1)
我要做的是使用向两个数据帧添加单调增加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|
+-----+---+-----------+---+
答案 1 :(得分:0)
想法草图:
通过
向数据框用户和展示次数添加单调增加的IDval indexedUsersDF = usersDf.withColumn("index", monotonicallyIncreasingId)
val indexedImpressionsDF = impressionsDf.withColumn("index", monotonicallyIncreasingId)
通过count
确定展示次数中的行数并存储为int,例如
val numberOfImpressions = ...
将UDF应用于indexedUsersDF
中的 index - 列,用于计算单独列中的模数(例如 moduloIndex )
val moduloIndexedUsersDF = indexedUsersDF.select(...)
加入moduloIndexedUsersDF
和indexedImperessionsDF
moduloIndexedUsersDF("moduloIndex")===indexedImpressions("index")