文章目录
注意:本文的分组,并没有聚合
假数据截图
先来看一下描述
这里分组没有聚合
原来pandas的groupby处理是对根据id分组后的每个组的df进行处理,方便理解起见看如下代码块:
换句话说,pandas里的groupby之后是可以遍历的,也就是可以遍历分组后的每个小df,如下:
# pandas实现
def pandas_gb(data):
# 根据id分组,处理每个分组后的df
for ids, da_gb in data.groupby('alpos_id'):
print(ids, len(da_gb))
if len(da_gb) < 5:
da_gb = da_gb.append(da_gb)
print(len(da_gb))
'''
out:
0_2011082923279930 11
11
0_3001461399082077 9
9
0_3031798112278383 4
8
0_3071297379437968 1
2
'''
比如里面打印的就是需求,当然实际上我对于分组后的每个小df处理上会更加复杂,这里为了方便演示就用上面的例子,现在想用pyspark来替换实现如上方式
groupby分组图例
pandas groupby分组图例
如果觉得不理解,也可以看下面这个图:
也就是说,pandas里是纵向的,但是在spark里确实横向的
pyspark groupby分组图例
按照上面pandas的例子,就是下图:
实现思路
import pandas as pd
from pyspark import SparkContext, SQLContext
from pyspark.sql import SparkSession
from pyspark.sql import functions as fn
sc = SparkContext()
ss = SparkSession(sc).builder \
.config("spark.driver.memory", "2g").config('spark.executor.memory', '2g')\
.config('spark.executor.cores', '2')\
.config('spark.driver.cores', '2')\
.config('spark.sql.shuffle.partitions', 200)\
.config("spark.debug.maxToStringFields", "100")\
.appName('to_hongzhen').getOrCreate()
sc.setLogLevel('ERROR')
由图可见,我们只需要循环的遍历每一行即可,直接看代码:
- 首先需要分组提取所需字段:
data = ss.createDataFrame(data)
da_gb = data.groupby('alpos_id').agg(
fn.collect_list('impressions').alias('impressions_list'),
fn.collect_list('ecpm').alias('ecpm_list')
)
da_gb.show()
- 通过map以RDD的形式来遍历每一行数据,这里的每一行数据其实就等同于上面pandas分组后的小df
dardds = da_gb.rdd.map(lambda data: ({data.alpos_id: [data.impressions_list, data.ecpm_list]}))
'''
0_3031798112278383 [4.0, 62.0, 58.0, 4.0] [2.5, 6.9355, 9.3103, 5.0]
0_3001461399082077 [0.2, 0.0, 0.142857142857142, 0.0, 0.181818181818181, 0.3, 0.3125, 0.0, 0.0] [43.6990133333333, 40.1434533333333, 41.21348, 34.8579266666666, 35.2619666666666, 35.6953, 44.22308, 44.4453, 44.18604]
0_3071297379437968 [8.0] [73.75]
0_2011082923279930 [222.0, 2269.0, 212.0, 43.0, 29.0, 172.0, 192.0, 232.0, 288.0, 306.0, 328.0] [14.4595, 14.0899, 14.3868, 12.5581, 12.069, 30.814, 14.1667, 12.6293, 15.5556, 8.5948, 11.2805]
'''
- 通过foeach的形式来对RDD每一行进行处理即可,比如这里还是以上面pandas的例子作为替换,需要的可以根据自己的需求来实现:
def row_dealwith(data):
ids = list(data.keys())[0]
values = data.get(ids)
# print(ids, values[0], values[1])
print(ids, len(values[0]))
print()
dardds.foreach(row_dealwith)
'''
0_3071297379437968 1
0_2011082923279930 11
0_3031798112278383 4
0_3001461399082077 9
'''