Python 3 对由 f(element) 分箱的数组中的元素进行计数的最具性能的方法

Python 3 Most Performative Way to count elements in an array binned by f(element)

提问人:Jennifer Kenney 提问时间:11/1/2023 更新时间:11/1/2023 访问量:19

问:

给定一个函数:

def foo_bar_bazzle(x):
   # do something, could be anything
   return result

和一个数组 arr (1 <= len(arr) <= 10**9) 的值来使用该函数进行评估,我想找到最有效的方法来查找元素计数,i 在 arr 中,按 foo_bar_bazzle(i) 的值分组。

这给了我正确的分组计数:

rslt_i = {}
for i in arr:
     rslt_i.setdefault(foo_bar_bazzle(i), []).append(i)

允许我对每个 foo_bar_bazzle(i) 的 len() 执行非关联操作:

return sum((len(v)**2 for v in rslt_i.values()))

但它不符合我的性能要求。在这里,我可以做些什么来加速 count(x) 组的 f(x)?

python-3.x 性能 分箱

评论

0赞 pho 11/1/2023
你所拥有的是最有性能的方式。如果是一个numpy数组/pandas数据帧并且能够对整个数组进行操作,那么您可以将繁重的计算工作外包给后端,但是根据问题中提供的信息,我认为您别无选择。arrfoo_bar_bazzle
0赞 Jérôme Richard 11/1/2023
在不做额外的假设的情况下,当前算法的时间复杂度是最佳的:。如果你想要更好的复杂性,那么你需要对目标函数或输入数组做一个额外的假设。O(n)
0赞 Jérôme Richard 11/1/2023
话虽如此,代码可以改进(不改变复杂性)。例如,您不需要在列表中发生,而只需通过递增与给定键关联的计数器来计算项目。此外,关于使用的类型,可以进一步改进操作。与特定代码相比,通用代码通常很慢。我怀疑数组类型无法知道,也无法知道函数(整数可能有优化)。尽管如此,无论如何,调用 10**9 次最终肯定会成为瓶颈(CPython 函数调用很慢)。ifoo_bar_bazzle
0赞 Jennifer Kenney 11/3/2023
我在这里的收获是,我应该将 arr 转换为一个 numpy 数组,并使我的函数在整个数组上工作。谢谢!

答: 暂无答案