1. approx_count_distinct和count_distinct
python
复制代码
#approx_count_distinct(col:ColumnOrName,rsd:Optionnal[float]=None)
"""
作用:返回列col的近似不同计数,返回一个新的列
场景:处理大数据计算时,获得一个精确结果开销很大,但是计算一个近似结果相对容易,此时可以使用approx_count_distinct函数
参数:
col:列名
rsd:结果允许的误差值,默认0.05
返回:
column:返回计算结果列
"""
#count_distinct(col:columnOrName)
"""
作用:返回列col不同计数,返回一个新的列
场景:获得一个列准确的不同元素的个数
参数:
col:列名
返回:
column:返回计算结果列
"""
TEST_DATA_DIR = "/opt/software/tmp/"
def write(filename,data):
with open(TEST_DATA_DIR+filename,'wt',encoding='utf-8') as f:
f.write(data)
def generate_test_file():
filename = "test.txt"
#初始data
data = ""
data_format = "{} {} {}\n"#分别存放id,name,score 随机生成100000条数据,统计score列不同数量
for i in range(100000):
data += data_format.format(i+1,'jack'+str(i),random.randint(0,100))
write(filename,data=data)
if __name__ == '__main__':
generate_test_file()
spark = SparkSession.builder.getOrCreate()
schema = StructType([StructField("id",StringType(),True),
StructField("name",StringType(),True),
StructField("score",StringType(),True)])
#读取文件
data = spark.sparkContext.textFile(TEST_DATA_DIR+'test.txt').map(lambda x:x.split(' ')).map(lambda x:Row(x[0],x[1],x[2]))
gradeDF=spark.createDataFrame(data,schema=schema)
gradeDF.select(approx_count_distinct('score',rsd=0.01)).show()
gradeDF.select(count_distinct('score')).show()
#输出结果
"""很明显是数据存在误差
+----------------------------+
|approx_count_distinct(score)|
+----------------------------+
| 99|
+----------------------------+
+---------------------+
|count(DISTINCT score)|
+---------------------+
| 101|
"""
+---------------------+
2. collect_list和collect_set:列转行
python
复制代码
#collect_list(col:ColumnOrName)
"""
作用:返回col列的list副本,该函数返回值顺序不确定
场景:列转行
参数:
col:列名
返回:
column:返回col列的list副本
"""
#collect_set(col:ColumnOrName)
"""
作用:返回col列的set副本,该函数返回值顺序不确定
场景:列转行
参数:
col:列名
返回:
column:返回col列的set副本
"""
spark = SparkSession.builder.getOrCreate()
#20110101销售商品数据
data = spark.createDataFrame([['20110101','A',22],['20110101','B',22],['20110102','A',33]],schema=['rq','produce_type','sl']) #
data.show()
data.createOrReplaceTempView("data")
spark.sql("select rq,collect_list(sl) as collect_list from data group by rq").show()
spark.sql("select rq,collect_set(sl) as collect_set from data group by rq").show()
#输出结果
"""
+--------+------------+---+
| rq|produce_type| sl|
+--------+------------+---+
|20110101| A| 22|
|20110101| B| 22|
|20110102| A| 33|
+--------+------------+---+
+--------+------------+
| rq|collect_list|
+--------+------------+
|20110101| [22, 22]|
|20110102| [33]|
+--------+------------+
+--------+-----------+
| rq|collect_set|
+--------+-----------+
|20110101| [22]|
|20110102| [33]|
+--------+-----------+
"""
3. corr:皮尔逊相关性
python
复制代码
#corr(col1:ColumnOrName,col2:ColumnOrName)
"""
作用:返回col1列和col2列的皮尔逊相关系数
场景:
参数:
col1:列名
col2:列名
返回:
column:返回col1列和col2列的皮尔逊相关系数
"""
spark = SparkSession.builder.getOrCreate()
a = range(20)
b = [2 * x for x in a]
data = spark.createDataFrame(zip(a,b),schema=['a','b'])
data.agg(corr('a','b').alias('c')).show()
data.createOrReplaceTempView("data")
spark.sql("select corr(a,b) as c from data").show()
#输出结果
"""
+---+
| c|
+---+
|1.0|
+---+
+---+
| c|
+---+
|1.0|
+---+
"""
4. covar_pop和covar_sample:返回列的总体协方差和样本协方差
python
复制代码
#covar_pop(col1:ColumnOrName,col2:ColumnOrName)
"""
作用:返回col1列和col2列的总体协方差
场景:
参数:
col1:列名
col2:列名
返回:
column:返回col1列和col2列的协方差
公式:
u0:x平均值 u1:y平均值
cov(x,y) = ((x1-u0)*(y1-u1)+(x2-u0)*(y2-u1)+...+(xN-u0)*(yN-u1))/N
例子:
X = [1,2,3] Y = [3,6,9]
u = 2 u = 6
cov(x,y) = ((1-2)*(3-6)+(2-2)*(6-6)+(3-2)*(6-9))/3 = 2
"""
#cover_samp(col1:ColumnOrName,col2:ColumnOrName)
"""
作用:返回col1列和col2列的样本协方差
场景:
参数:
col1:列名
col2:列名
返回:
column:返回col1列和col2列的样本协方差
公式:
u0:x平均值 u1:y平均值
cov(x,y) = ((x1-u0)*(y1-u1)+(x2-u0)*(y2-u1)+...+(xN-u0)*(yN-u1))/(N-1)
例子:
X = [1,2,3] Y = [3,6,9]
u = 2 u = 6
cov(x,y) = ((1-2)*(3-6)+(2-2)*(6-6)+(3-2)*(6-9))/2 = 3
"""
#总体协方差和样本协方差区别重点是分母不同,总体协方差为N,样本协方差为N-1
spark = SparkSession.builder.getOrCreate()
data = spark.createDataFrame([(1,3),(2,6),(3,9)],schema=['a','b'])
# ((1-2)*(3-6)+(2-2)*(6-6)+(3-2)*(9-6))/3 = 2
data.agg(covar_pop('a','b').alias('covar_pop')).show()
data.agg(covar_samp('a','b').alias('covar_samp')).show()
#((1-2)*(3-6)+(2-2)*(6-6)+(3-2)*(9-6))/2 = (3+3)/2 = 3
#输出如下:
+---------+
|covar_pop|
+---------+
| 2.0|
+---------+
+----------+
|covar_samp|
+----------+
| 3.0|
+----------+
5. first:返回集合中第一个元素 last:返回集合中最后一个元素
python
复制代码
#first(col:ColumnOrName,ignorenulls:ColumnOrName)
"""
作用:返回该组第一个数值,和groupBy合用,会显示分组之后,各个组的第一个
场景:
参数:
col:列名
ignorenulls:是否忽略控制
返回:
column:返回该组第一个数值
"""
#last(col:ColumnOrName,ignorenulls:ColumnOrName)
"""
作用:返回该组第最后一个数值,和groupBy合用,会显示分组之后,各个组的最后一个
场景:
参数:
col:列名
ignorenulls:是否忽略控制
返回:
column:返回该组第最后一个数值
"""
data = spark.createDataFrame([('Alice',2),('Bob',5),('Alice',12),('Bob',32),('Alice',None)],schema=("name","age"))
print("按照age排序前")
data.groupby('name').agg(first("age")).show()
data.groupby('name').agg(first("age", ignorenulls=True)).show()
print("按照age倒排序后")
data = data.orderBy("age",ascending=False)
data.groupby('name').agg(first("age")).show()
data.groupby('name').agg(first("age", ignorenulls=True)).show()
#last
data.groupby('name').agg(last("age")).show()
data.groupby('name').agg(last("age", ignorenulls=True)).show()
print("按照age倒排序后")
data = data.orderBy("age", ascending=False)
data.groupby('name').agg(last("age")).show()
data.groupby('name').agg(last("age", ignorenulls=True)).show()
#输出如下:
"""
按照age排序前
+-----+----------+
| name|first(age)|
+-----+----------+
| Bob| 5|
|Alice| 2|
+-----+----------+
+-----+----------+
| name|first(age)|
+-----+----------+
| Bob| 5|
|Alice| 2|
+-----+----------+
按照age倒排序后
+-----+----------+
| name|first(age)|
+-----+----------+
| Bob| 32|
|Alice| 12|
"""
data = data.sort(data['age'].asc())
data.createOrReplaceTempView("data")
spark.sql("select name,first(age) from data where age >0 group by name ").show()
#输出如下:
"""
+-----+----------+
| name|first(age)|
+-----+----------+
| Bob| 5|
|Alice| 2|
+-----+----------+
#last
+-----+---------+
| name|last(age)|
+-----+---------+
| Bob| 32|
|Alice| null|
+-----+---------+
+-----+---------+
| name|last(age)|
+-----+---------+
| Bob| 32|
|Alice| 12|
+-----+---------+
按照age倒排序后
+-----+---------+
| name|last(age)|
+-----+---------+
| Bob| 5|
|Alice| null|
+-----+---------+
+-----+---------+
| name|last(age)|
+-----+---------+
| Bob| 5|
|Alice| 2|
+-----+---------+
"""
6. grouping:判断是否聚合
python
复制代码
#grouping(col:ColumnOrName)
"""
作用:
场景:
参数:
col:列名
返回:
column:如果聚合返回1,否则返回0
"""
data = spark.createDataFrame([('Alice', 2), ('Bob', 5), ('Alice', 12), ('Bob', 32)],
schema=("name", "age"))
data.cube('name').agg(grouping('name'),count("age")).show()
#输出如下:
"""
data = spark.createDataFrame([('Alice', 2), ('Bob', 5), ('Alice', 12), ('Bob', 32)],
schema=("name", "age"))
data.cube('name').agg(grouping('name'),count("age")).show()
"""
python
复制代码
"""
max:返回集合中最大元素
min:返回集合中最小元素
mean:返回集合元素中平均数 过滤空值
avg:和mean一样 过滤空值
median:返回结合中元素中位数
sum:返回集合元素中元素之和
count:返回集合元素个数 过滤空值
product:返回集合中元素的乘积
"""
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
"""
#姓名 科目 成绩
data = spark.createDataFrame([('tom','math',32),('tom','english',50),('tom','chinese',90),
('jack','math',62),('jack','english',70),('jack','chinese',80),
('danny','math',92),('danny','english',80),('danny','chinese',70)
],schema=['name','subject','score'])
#最大元素
data.groupby('name').agg(max('score')).show()
data.agg(max('score')).show()
#输出如下:
+-----+----------+
| name|max(score)|
+-----+----------+
| jack| 80|
| tom| 90|
|danny| 92|
+-----+----------+
+----------+
|max(score)|
+----------+
| 92|
+----------+
#最小元素
data.groupby('subject').agg(min('score')).show()
data.agg(min('score')).show()
#输出如下:
+-----+----------+
| name|min(score)|
+-----+----------+
| jack| 62|
| tom| 32|
|danny| 70|
+-----+----------+
+----------+
|min(score)|
+----------+
| 32|
+----------+
#mean平均值
#最大元素
data.groupby('name').agg(mean('score')).show()
data.agg(mean('score')).show()
#输出如下:
+-----+------------------+
| name| avg(score)|
+-----+------------------+
| jack| 70.66666666666667|
| tom|57.333333333333336|
|danny| 80.66666666666667|
+-----+------------------+
+-----------------+
| avg(score)|
+-----------------+
|69.55555555555556|
+-----------------+
#median中位数
data.groupby('name').agg(median('score')).show()
data.agg(median('score')).show()
#sum求和
data.groupby('name').agg(sum('score')).show()
data.agg(sum('score')).show()
#输出如下:
"""
+-----+----------+
| name|sum(score)|
+-----+----------+
| jack| 212|
| tom| 172|
|danny| 242|
+-----+----------+
+----------+
|sum(score)|
+----------+
| 626|
+----------+
"""
#count元素个数
data.groupby('name').agg(count('score')).show()
data.agg(count('score')).show()
#输出如下:
"""
+-----+------------+
| name|count(score)|
+-----+------------+
| jack| 3|
| tom| 3|
|danny| 3|
+-----+------------+
+------------+
|count(score)|
+------------+
| 9|
+------------+
"""
#product:返回乘积
data.groupby('name').agg(product('score')).show()
data.agg(product('score')).show()
#输出如下:
+-----+--------------+
| name|product(score)|
+-----+--------------+
| jack| 347200.0|
| tom| 144000.0|
|danny| 515200.0|
+-----+--------------+
+--------------+
|product(score)|
+--------------+
|2.575835136E16|
+--------------+
8. sum_distinct:不同元素求和
python
复制代码
#sum_distinct不同元素求和,只有列中元素不同才进行加法运算
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
"""
spark = SparkSession.builder.getOrCreate()
data = spark.createDataFrame([('tom', 'math', 32), ('tom', 'english', 32), ('tom', 'chinese', 32), ('jack', 'math', 32), ('jack', 'english', 32), ('jack', 'chinese', 32),
('danny', 'math', 32), ('danny', 'english', 32), ('danny', 'chinese', 32)], schema=['name', 'subject', 'score'])
data.groupby('name').agg(sum_distinct('score')).show()
data.agg(sum_distinct('score')).show()
#输出如下:
"""
+-----+-------------------+
| name|sum(DISTINCT score)|
+-----+-------------------+
| jack| 32|
|danny| 32|
| tom| 32|
+-----+-------------------+
+-------------------+
|sum(DISTINCT score)|
+-------------------+
| 32|
+-------------------+
"""
9. var_pop:方差 var_pop:样本方差 variance:方差
python
复制代码
#如果数据集合存在空值,则过滤掉,分母也减掉这个元素
#var_pop:返回该列的总体方差
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
公式:
u:(x1,x2,...,XN)平均数
[(x1-u)**2+(x2-u)**2+...+(xN-u)**2]/N
"""
#var_samp:返回该列的样本方差
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
公式:
u:(x1,x2,...,XN)平均数
[(x1-u)**2+(x2-u)**2+...+(xN-u)**2]/(N-1)
"""
#variance:方差,公式和var_samp一致
spark = SparkSession.builder.getOrCreate()
data = spark.createDataFrame([('tom', 'math', 1), ('tom', 'english', 2), ('tom', 'chinese', 3),('jack', 'math', 1), ('jack', 'english', 2), ('jack', 'chinese', 3),
('danny', 'math', 1), ('danny', 'english', 2), ('danny', 'chinese', 3)], schema=['name', 'subject', 'score'])
data.groupBy('name').agg(var_pop("score")).show()
data.agg(var_pop("score")).show()
#var_pop x = 1 2 3 u=2 [(1-2)**2+(2-2)**2+(3-2)**2]/3 = 0.66666
#输出如下:
"""
+-----+------------------+
| name| var_pop(score)|
+-----+------------------+
| jack|0.6666666666666666|
| tom|0.6666666666666666|
|danny|0.6666666666666666|
+-----+------------------+
+------------------+
| var_pop(score)|
+------------------+
|0.6666666666666666|
+------------------+
"""
#var_samp:样本方差
data.groupBy('name').agg(var_samp("score")).show()
data.agg(var_samp("score")).show()
#输出如下:
"""
+-----+---------------+
| name|var_samp(score)|
+-----+---------------+
| jack| 1.0|
| tom| 1.0|
|danny| 1.0|
+-----+---------------+
+---------------+
|var_samp(score)|
+---------------+
| 0.75|
+---------------+
"""
#测试存在None值
spark = SparkSession.builder.getOrCreate()
data = spark.createDataFrame([('tom', 'math', 1), ('tom', 'english', 2), ('tom', 'chinese', None) ], schema=['name', 'subject', 'score'])
data.groupBy('name').agg(var_pop("score")).show()
#均值:(1+2)/2=1.5 方差((1-1.5)**2+(2-1.5)**2)/2 = 0.25
#输出如下:
"""
+-----+------------------+
| name| var_pop(score)|
+-----+------------------+
|tom| 0.25|
+-----+------------------+
"""
10. stddev:标准差 stddev_pop:总体标准差 stddev_samp:样本标准差
python
复制代码
#如果数据集合存在空值,则过滤掉,分母也减掉这个元素
#stddev:返回该列的标准差
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
公式:
u:(x1,x2,...,XN)平均数
math.sqrt([(x1-u)**2+(x2-u)**2+...+(xN-u)**2]/(N-1))
"""
#stddev_pop:返回该列的总体标准差
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
公式:
u:(x1,x2,...,XN)平均数
math.sqrt([(x1-u)**2+(x2-u)**2+...+(xN-u)**2]/N)
"""
#stddev_samp:返回该列的样本标准差
"""
作用:
场景:
参数:
col:列名
返回:
column:返回对应结果
公式:
u:(x1,x2,...,XN)平均数
math.sqrt([(x1-u)**2+(x2-u)**2+...+(xN-u)**2]/(N-1))
"""
spark = SparkSession.builder.getOrCreate()
data = spark.createDataFrame([('tom', 'math', 3), ('tom', 'english', 4), ('tom', 'chinese', 5),('jack', 'math', 3), ('jack', 'english', 4), ('jack', 'chinese', 5),
('danny', 'math', 3), ('danny', 'english', 4), ('danny', 'chinese', 5)], schema=['name', 'subject', 'score'])
# 最大元素
data.groupBy('name').agg(stddev("score").alias('stddev')).show() #mean:过滤空值 avg:过滤空值
data.groupBy('name').agg(stddev_pop("score")).show()
data.groupBy('name').agg(stddev_samp("score")).show()
#输出如下:
"""
+-----+------+
| name|stddev|
+-----+------+
| jack| 1.0|
| tom| 1.0|
|danny| 1.0|
+-----+------+
+-----+-----------------+
| name|stddev_pop(score)|
+-----+-----------------+
| jack|0.816496580927726|
| tom|0.816496580927726|
|danny|0.816496580927726|
+-----+-----------------+
+-----+------------------+
| name|stddev_samp(score)|
+-----+------------------+
| jack| 1.0|
| tom| 1.0|
|danny| 1.0|
+-----+------------------+
"""