【发布时间】:2019-02-28 09:14:51
【问题描述】:
考虑表格:
df=sc.parallelize([(1,1,1),(5,0,2),(27,1,1),(1,0,3),(5,1,1),(1,0,2)]).toDF(['id', 'error', 'timestamp'])
df.show()
+---+-----+---------+
| id|error|timestamp|
+---+-----+---------+
| 1| 1| 1|
| 5| 0| 2|
| 27| 1| 1|
| 1| 0| 3|
| 5| 1| 1|
| 1| 0| 2|
+---+-----+---------+
我想在timestamp 列上进行透视,保留原始表中的一些其他汇总信息。我感兴趣的结果可以通过
df1=df.groupBy('id').agg(sf.sum('error').alias('Ne'),sf.count('*').alias('cnt'))
df2=df.groupBy('id').pivot('timestamp').agg(sf.count('*')).fillna(0)
df1.join(df2, on='id').filter(sf.col('cnt')>1).show()
使用结果表:
+---+---+---+---+---+---+
| id| Ne|cnt| 1| 2| 3|
+---+---+---+---+---+---+
| 5| 1| 2| 1| 1| 0|
| 1| 1| 3| 1| 1| 1|
+---+---+---+---+---+---+
但是,上述解决方案至少存在两个问题:
- 我在脚本末尾按
cnt过滤。如果我一开始就可以做到这一点,我可以避免几乎所有的处理,因为使用这种过滤会删除大部分数据。除了collect和isin方法之外,还有什么方法可以做到这一点? - 我在
id上做了两次groupBy。首先,聚合我在结果中需要的一些列,第二次获取数据透视列。最后,我需要join来合并这些列。我觉得我肯定错过了一些解决方案,因为应该可以只使用一个groubBy而没有join,但我不知道该怎么做。
【问题讨论】:
-
您可以将过滤器移动到第一个 groupBy 查询,并且只过滤 df1 上的 cnt>1。这不应该改变你的结果
标签: dataframe group-by pyspark pivot-table