假设我有一个Pyspark数据帧,如下所示。每个用户在某个特定日期购买了一件商品。
+--+-------------+-----------+
|ID| Item Bought| Date |
+--+-------------+-----------+
|1 | Laptop | 01/01/2018|
|1 | Laptop | 12/01/2017|
|1 | Car | 01/12/2018|
|2 | Cake | 02/01/2018|
|3 | TV | 11/02/2017|
+--+-------------+-----------+
现在我想创建一个新的数据框,如下所示。
+---+--------+-----+------+----+
|ID | Laptop | Car | Cake | TV |
+---+--------+-----+------+----+
|1 | 2 | 1 | 0 | 0 |
|2 | 0 | 0 | 1 | 0 |
|3 | 0 | 0 | 0 | 1 |
+---+--------+-----+------+----+
有项目列,每列有一个项目。对于每个用户,每列上的数字是用户购买的项目数。
答案 0 :(得分:2)
如果pyspark中的数据是像这样的数据框
df = sc.parallelize(([(1, 'laptop', '01/01/2018'),
(1, 'laptop', '12/01/2017'),
(1, 'car', '01/12/2018'),
(2, 'cake', '02/01/2018'),
(3, 'tv', '11/02/2017')])).toDF(['id', 'item bought', 'date'])
现在,您可以使用groupby和pivot操作来获得结果。
df2 = (df.groupby(['id']).pivot('item bought', ['tv','cake', 'laptop',"car"]).
count().fillna(0).show())
df2.show()
结果
+---+---+----+------+---+
| id| tv|cake|laptop|car|
+---+---+----+------+---+
| 1| 0| 0| 2| 1|
| 3| 1| 0| 0| 0|
| 2| 0| 1| 0| 0|
+---+---+----+------+---+
请记住,在透视操作中,没有必要提供不同的值,但提供这些值会加快过程。
答案 1 :(得分:0)
另一种解决方案,
import pyspark.sql.functions as F
df = sc.parallelize([
(1,'Laptop','01/01/2018'), (1, 'Laptop','12/01/2017'),(1,'Car','01/12/2018'),
(2 ,'Cake', '02/01/2018'),(3,'TV','11/02/2017')]).toDF(['ID','Item','Date'])
items = sorted(df.select("Item").distinct().rdd\
.map(lambda row: row[0])\
.collect())
cols = [F.when(F.col("Item") == m, F.col("Item")).otherwise(None).alias(m) for m in items]
counts = [F.count(F.col(m)).alias(m) for m in items]
df_reshaped = df.select(F.col("ID"), *cols)\
.groupBy("ID")\
.agg(*counts)
df_reshaped.show()