首页 > 解决方案 > 并行计算的列统计

问题描述

在 Spark 数据框列中获取最大值的最佳方法

这篇文章展示了如何在一个表上运行聚合(distinct、min、max),例如:

for colName in df.columns:
    dt = cd[[colName]].distinct().count()
    mx = cd.agg({colName: "max"}).collect()[0][0]
    mn = cd.agg({colName: "min"}).collect()[0][0]
    print(colName, dt, mx, mn)

这可以通过计算统计数据轻松完成。Hive 和 spark 的统计数据不同:

看起来有很多统计数据被计算出来。如何使用一个命令获取所有列的所有内容?

但是,我有 1000 列,并且连续执行此操作非常慢。假设我想在每一列上计算一些其他函数,比如标准偏差——如何并行完成?

标签: hivepysparkstatistics

解决方案


您可以使用pyspark.sql.DataFrame.describe()这些统计信息适用于所有列的聚合统计信息,例如计数、平均值、最小值、最大值和标准差。(如果不传入任何参数,则默认返回所有列的统计信息)

df = spark.createDataFrame(
    [(1, "a"),(2, "b"), (3, "a"), (4, None), (None, "c")],["id", "name"]
)
df.describe().show()
#+-------+------------------+----+
#|summary|                id|name|
#+-------+------------------+----+
#|  count|                 4|   4|
#|   mean|               2.5|null|
#| stddev|1.2909944487358056|null|
#|    min|                 1|   a|
#|    max|                 4|   c|
#+-------+------------------+----+

如您所见,这些统计信息忽略了任何null值。

如果您使用的是 spark 2.3 版,那么还有pyspark.sql.DataFrame.summary()一个支持以下聚合:

count - mean - stddev - min - max - 指定为百分比的任意近似百分位数(例如,75%)

df.summary("count", "min", "max").show()
#+-------+------------------+----+
#|summary|                id|name|
#+-------+------------------+----+
#|  count|                 4|   4|
#|    min|                 1|   a|
#|    max|                 4|   c|
#+-------+------------------+----+

如果您想要所有列的其他聚合统计信息,您还可以使用带有pyspark.sql.DataFrame.agg(). 例如,如果您想复制您所说的 Hive 提供的内容(不同、最大、最小和空值 - 我不确定长度和版本的含义):

import pyspark.sql.functions as f
from itertools import chain

agg_distinct = [f.countDistinct(c).alias("distinct_"+c) for c in df.columns]
agg_max = [f.max(c).alias("max_"+c) for c in df.columns]
agg_min = [f.min(c).alias("min_"+c) for c in df.columns]
agg_nulls = [f.count(f.when(f.isnull(c), c)).alias("nulls_"+c) for c in df.columns]

df.agg(
    *(chain.from_iterable([agg_distinct, agg_max, agg_min, agg_nulls]))
).show()
#+-----------+-------------+------+--------+------+--------+--------+----------+
#|distinct_id|distinct_name|max_id|max_name|min_id|min_name|nulls_id|nulls_name|
#+-----------+-------------+------+--------+------+--------+--------+----------+
#|          4|            3|     4|       c|     1|       a|       1|         1|
#+-----------+-------------+------+--------+------+--------+--------+----------+

尽管此方法将返回一行,而不是每个统计信息都返回describe()一行summary()


推荐阅读