Python 为spark dataframe中的用户的每个项目创建每一行

Python 为spark dataframe中的用户的每个项目创建每一行,python,apache-spark,apache-spark-sql,Python,Apache Spark,Apache Spark Sql,我有一个spark数据框,如下所示: User Item Purchased 1 A 1 1 B 2 2 A 3 2 C 4 3 A 3 3 B 2 3 D 6 only showing top 5 rows User Item Purchased 1 A 1 1 B 2 1 C 0 1 D 0 2 A 3 2 C 4 2 B 0 2 D 0 3

我有一个spark数据框,如下所示:

  User  Item    Purchased
1   A   1
1   B   2
2   A   3
2   C   4
3   A   3
3   B   2
3   D   6

only showing top 5 rows
User    Item    Purchased
1   A   1
1   B   2
1   C   0
1   D   0
2   A   3
2   C   4
2   B   0
2   D   0
3   A   3
3   B   2
3   D   6
3   C   0
only showing top 5 rows
每个用户都有一行用于他们购买的商品。假设Purhcased为多少数量。购买(计数)

但是,有些项目用户可能没有购买,因此对于该项目,特定用户没有行。我们只有用户购买的项目的行。因此,如果用户1购买了项目A、B,那么用户1有两行对应于这两个项目。但是如果用户2购买了A,C,那么用户2就有A和C项的行,但没有B项。我希望最终每个用户都应该有表中所有项目的所有行,以及每个项目的相应计数

我想将此数据帧转换为如上所述的数据帧,但也包含用户未看到的项目的行,并将相应的计数设为零

如下图所示:

  User  Item    Purchased
1   A   1
1   B   2
2   A   3
2   C   4
3   A   3
3   B   2
3   D   6

only showing top 5 rows
User    Item    Purchased
1   A   1
1   B   2
1   C   0
1   D   0
2   A   3
2   C   4
2   B   0
2   D   0
3   A   3
3   B   2
3   D   6
3   C   0
only showing top 5 rows
我想到的一种方法是,在spark中,如果我在第一个数据帧上使用sqlContext的cross_tab方法,那么我可以将每一行转换为具有相应值的列。对于用户没有的项,它将为该项创建一列,并将零放在那里

但是如何将这些列转换回行呢?。这也可能是一种迂回的方式


谢谢

我们也可以通过只使用
df
函数来实现这一点

orders = [(1,"A",1),(1,"B",2),(2,"A",3),(2,"C",4),(3,"A",3),(3,"B",2),(3,"D",6)]
df = sqlContext.createDataFrame(orders, ["user","item","purchased"])
df_items = df.select("item").distinct().repartition(5).withColumnRenamed("item", "item_1")
df_users = df.select("user").distinct().repartition(5).withColumnRenamed("user", "user_1")
df_cartesian = df_users.join(df_items)
//above expression returns cartesian product of users and items dfs
joined_df = df_cartesian.join(df, [df_cartesian.user_1==df.user, df_cartesian.item_1==df.item], "left_outer").drop("user").drop("item")
result_df = joined_df.fillna(0,["purchased"]).withColumnRenamed("item_1", "item").withColumnRenamed("user_1", "user")
最后,
result\u df.show()
生成如下所示的期望输出:

+----+----+---------+
|user|item|purchased|
+----+----+---------+
|   2|   A|        3|
|   2|   B|        0|
|   2|   C|        4|
|   2|   D|        0|
|   3|   A|        3|
|   3|   B|        2|
|   3|   C|        0|
|   3|   D|        6|
|   1|   A|        1|
|   1|   B|        2|
|   1|   C|        0|
|   1|   D|        0|
+----+----+---------+

我需要重新分区吗?需要,否则
df\u用户。加入(df\u项目)
创建
200*200
任务。其中200是默认的分区数。问题是它没有运行。运行超过12小时,甚至没有结果。我有30万个obs。您是否重新划分了
用户
项目
表?每个
用户
项目
表中有多少行(不同)?输入数据的大小是多少?我按照指示进行了重新分区。我的数据帧是300K行。有56K个不同的用户和8.5K个不同的项目。然而,56x8.5K不等于300k,因为我们只有用户购买的用户项目行。如果用户没有购买物品,则该物品不在那里。就像上面的第一个表一样。这里的purchase\u count变量是什么?还有为什么要取平均数呢?我想要实际的计数,因为它在dataOk中,这段代码运行需要很长时间。我在我的笔记本电脑上运行它,但是时间太长了consuming@Baktaawar我把purchase命名为purchase\u count。编辑我的代码以反映这一点。不知道为什么花了这么长时间。我在我的笔记本电脑上运行了1249956行,它在4秒内运行。下面是创建示例输入的代码<代码>输出=[]字母表=列表(字符串.大写)表示范围内的i(1100000):mod=i%len(字母表)表示范围内的j(0,mod):输出。追加((i,字母表[j],1))我不知道。您的代码持续运行了12个小时,但没有完成。所以我不得不使用@avr的以下代码。它运行了45分钟。我有56K个用户,表中有8.5K个不同的项目。我的项目名称不是单个字符。它是长字符串。不建议在大数据集上执行
collect()
,它应该用于小数据集和调试目的。