我有两个这样的数据框:
| User |
------
| 1 |
| 2 |
| 3 |
和
| Articles |
----------
| 'A' |
| 'B' |
| 'C' |
什么是随机分配每个用户2 articles
的直观方式?
输出数据框可能如下所示:
| User | Articles |
-----------------
| 1 | 'A' |
| 1 | 'C' |
| 2 | 'C' |
| 2 | 'B' |
| 3 | 'C' |
| 3 | 'A' |
以下是生成这两个数据帧的代码:
u =[(1,), (2,), (3,)]
rdd = sc.parallelize(u)
users = rdd.map(lambda x: Row(user_id=x[0]))
users_df = sqlContext.createDataFrame(users)
a = [('A',), ('B',), ('C',), ('D',), ('E',)]
rdd = sc.parallelize(a)
articles = rdd.map(lambda x: Row(article_id=x[0]))
articles_df = sqlContext.createDataFrame(articles)
答案 0 :(得分:0)
由于您的文章列表很小,因此将其保留为python对象而不是分布式列表是有意义的。这将允许您创建一个udf来为每个user_id生成一个随机的文章列表。以下是您可以这样做的一种方式:
from random import sample,seed
from pyspark.sql import Row
from pyspark.sql.functions import udf,explode
from pyspark.sql.types import ArrayType,StringType
class ArticleRandomizer(object):
def __init__(self,article_list,num_articles=2,preseed=0):
self.article_list=article_list
self.num_articles=num_articles
self.preseed=preseed
def getrandom(self,user):
seed(user+self.preseed)
return sample(self.article_list,self.num_articles)
u =[(1,), (2,), (3,)]
rdd = sc.parallelize(u)
users = rdd.map(lambda x: Row(user_id=x[0]))
users_df = sqlContext.createDataFrame(users)
a = [('A',), ('B',), ('C',), ('D',), ('E',)]
#rdd = sc.parallelize(a)
#articles = rdd.map(lambda x: Row(article_id=x[0]))
#articles_df = sqlContext.createDataFrame(articles)
article_list=[article[0] for article in a]
ARandomizer=ArticleRandomizer(article_list)
add_articles=udf(ARandomizer.getrandom,ArrayType(StringType()))
users_df.select('user_id',explode(add_articles('user_id'))).show()
此ArticleRandomizer.getrandom
函数由user_id
播种,因此它是确定性的,这意味着您将为每次运行获得给定用户的相同随机文章列表。您可以通过在实例化类时更改preseed
值来调整此值以获取可能不同的列表。
尚未对此进行测试以确定它是否可以很好地扩展,但它应该可以在数据集上正常工作,因为文章和用户的维度都相当小。