我想找到将describe
函数应用到分组DataFrame的最简洁方法(这个问题还会扩大到将任何DF函数应用到分组DF)
我没有运气就测试了成群的大熊猫UDF。始终可以通过在agg
函数内部传递每个统计信息来做到这一点,但这不是正确的方法。
如果我们有一个示例数据框:
df = spark.createDataFrame(
[(1, 1.0), (1, 2.0), (2, 3.0), (2, 5.0), (2, 10.0)],
("id", "v"))
这个想法是做类似于熊猫的事情:
df.groupby("id").describe()
结果将是:
v
count mean std min 25% 50% 75% max
id
1 2.0 1.5 0.707107 1.0 1.25 1.5 1.75 2.0
2 3.0 6.0 3.605551 3.0 4.00 5.0 7.50 10.0
谢谢。
答案 0 :(得分:0)
尝试一下:
df.groupby("id").agg(F.count('v').alias('count'), F.mean('v').alias('mean'), F.stddev('v').alias('std'), F.min('v').alias('min'), F.expr('percentile(v, array(0.25))')[0].alias('%25'), F.expr('percentile(v, array(0.5))')[0].alias('%50'), F.expr('percentile(v, array(0.75))')[0].alias('%75'), F.max('v').alias('max')).show()
输出:
+---+-----+----+------------------+---+----+---+----+----+
| id|count|mean| std|min| %25|%50| %75| max|
+---+-----+----+------------------+---+----+---+----+----+
| 1| 2| 1.5|0.7071067811865476|1.0|1.25|1.5|1.75| 2.0|
| 2| 3| 6.0| 3.605551275463989|3.0| 4.0|5.0| 7.5|10.0|
+---+-----+----+------------------+---+----+---+----+----+
答案 1 :(得分:0)
如果您具有实用程序功能模块,则可以在其中放入类似的内容,然后再调用一个衬板。
import pyspark.sql.functions as F
def groupby_apply_describe(df, groupby_col, stat_col):
"""From a grouby df object provide the stats
of describe for each key in the groupby object.
Parameters
----------
df : spark dataframe groupby object
col : column to compute statistics on
"""
output = df.groupby(groupby_col).agg(
F.count(stat_col).alias("count"),
F.mean(stat_col).alias("mean"),
F.stddev(stat_col).alias("std"),
F.min(stat_col).alias("min"),
F.expr(f"percentile({stat_col}, array(0.25))")[0].alias("%25"),
F.expr(f"percentile({stat_col}, array(0.5))")[0].alias("%50"),
F.expr(f"percentile({stat_col}, array(0.75))")[0].alias("%75"),
F.max(stat_col).alias("max"),
)
print(output.orderBy(groupby_col).show())
return output
在您的情况下,您将致电groupby_apply_describe(df, 'id', 'v')
。输出应符合您的要求。
答案 2 :(得分:0)
受到之前答案的启发,但在spark/3.0.1
中进行了测试
import pyspark.sql.functions as F
from functools import reduce
group_column = 'id'
metric_columns = ['v','v1','v2']
# You will have a dataframe with df variable
def spark_describe(group_col, stat_col):
return df.groupby(group_col).agg(
F.count(stat_col).alias(f"{stat_col}_count"),
F.mean(stat_col).alias(f"{stat_col}_mean"),
F.stddev(stat_col).alias(f"{stat_col}_std"),
F.min(stat_col).alias(f"{stat_col}_min"),
F.max(stat_col).alias("{stat_col}_max"),
F.expr(f"percentile({stat_col}, array(0.25))")[0].alias(f"{stat_col}_25pct"),
F.expr(f"percentile({stat_col}, array(0.5))")[0].alias(f"{stat_col}_50pct"),
F.expr(f"percentile({stat_col}, array(0.75))")[0].alias(f"{stat_col}_75pct"),
)
_join = lambda a,b: a.join(b, group_column, 'inner')
dff = reduce(_join, list(map(lambda x: spark_describe(*x), zip(it.repeat(group_column, len(metric_columns)), metric_columns))))
答案 3 :(得分:-1)
您将运行以下代码:
df.groupby("id").describe('uniform', 'normal').show()
这是不言自明的。