PySpark 2.1.1 groupby + approx_count_distinct 计数为 0

Posted

技术标签:

【中文标题】PySpark 2.1.1 groupby + approx_count_distinct 计数为 0【英文标题】:PySpark 2.1.1 groupby + approx_count_distinct giving counts of 0 【发布时间】:2017-10-05 14:47:14 【问题描述】:

我正在使用 Spark 2.1.1 (pyspark),在大约 14 亿行的 DataFrame 上进行 groupby,然后进行 approx_count_distinct 聚合。 groupby 操作导致大约 600 万组要对其执行 approx_count_distinct 操作。组的预期不同计数范围从个位数到数百万不等。

这是我正在使用的代码 sn-p,“item_id”列包含项目 ID,“user_id”包含用户 ID。我想计算与每个项目关联的不同用户。

>>> distinct_counts_df = data_df.groupby(['item_id']).agg(approx_count_distinct(data_df.user_id).alias('distinct_count'))

在生成的 DataFrame 中,我得到了大约 16,000 个计数为 0 的项目:

>>> distinct_counts_df.filter(distinct_counts_df.distinct_count == 0).count()
16032

当我检查其中一些项目的实际不同计数时,我得到了 20 到 60 之间的数字。这是 HLL 近似计数算法的准确性的已知问题还是一个错误?

【问题讨论】:

【参考方案1】:

虽然我不确定实际问题出在哪里,但由于 approx_count_distinct 依赖于近似值(https://***.com/a/40889920/7045987),HLL 很可能是问题所在。

你可以试试这个:

有一个参数 'rsd' 可以传入 approx_count_distinct 来确定误差范围。如果 rsd = 0,尽管时间会显着增加,但它会给你准确的结果,在这种情况下,countDistinct 成为更好的选择。不过,您可以尝试以增加时间为代价将 rsd 降低到 0.008。这可能有助于提供更准确的结果。

【讨论】:

感谢您的建议。我尝试使用 rsd=0.008。运行时间大约是原来的 10 倍,但是我在结果中得到了相同数量的 0,所以它没有解决问题。 那么我猜结果将保持在这个程度。在大多数情况下,approx_count_distinct 不会给出正确的结果。看到这个databricks.com/blog/2016/05/19/…

以上是关于PySpark 2.1.1 groupby + approx_count_distinct 计数为 0的主要内容,如果未能解决你的问题,请参考以下文章

从 Pandas groupBy 到 PySpark groupBy

pyspark groupby 并创建包含其他列字典的列

pyspark:groupby 和聚合 avg 和 first 在多个列上

Pyspark 中的 Groupby 和标准化值

如何使用 groupby 和聚合将 pyspark 数据框中的行与多列连接起来

从 PySpark GroupBy 中的两列创建 JSON 字符串