Numpy的分区比小数组的排序慢

时间:2017-04-24 12:57:40

标签: python arrays performance sorting numpy

我一直在寻找一种有效的方法来计算numpy数组中的第n个最大值,并this answer将我引导到np.partition

顺便说一句,我注意到,对于短于100个条目的数组,天真排序比np.partition方法更快。 (对于大型阵列,相反,增益很明显)

对于小型数组,np.partition运行时间几乎是平的是什么原因?

enter image description here

生成图片的代码:

import pandas as pd
import numpy as np

import timeit

def func_1(inp):
    return np.partition(inp, 10)[10]

def func_2(inp):
    return np.sort(inp)[10]

a = []
b = []

N_tests = int(1e5)

for wdw in range(20, 1000, 10):

    print wdw

    res1 = timeit.timeit("func_1(test)",
                      setup = "import pandas as pd; import numpy as np; wdw_size = %d; test = np.random.randn(wdw_size); from __main__ import func_1"%wdw, number = N_tests)

    a.append(res1)

    res2 = timeit.timeit("func_2(test)",
                      setup = "import pandas as pd; import numpy as np; wdw_size = %d; test = np.random.randn(wdw_size); from __main__ import func_2"%wdw, number = N_tests)

    b.append(res2)

import matplotlib.pyplot as plt
plt.plot(range(20,1000, 10), a, range(20, 1000, 10), b)
plt.legend(['np.partition', 'np.sort'])
plt.xlabel('Array Size')
plt.ylabel('Time')

1 个答案:

答案 0 :(得分:1)

根据文档,np.partition是通过 Introselect 实施的 - 这是一种性能最差 O(n)的算法。

在一句话中, Introselect 是快速排序的加强版本,只需median of medians的帮助。

另一方面,np.sort是使用普通的快速排序实现的,其性能最差 O(n ^ 2)

所以要对两者进行比较,而np.sort只使用快速排序,最终可能会以 O(n ^ 2 )作为最差情况,np.partition可以通过在必要时减少中位数的中位数来避免这种情况,以确保 O(n)

不完全确定但是np.sort对于小型数组而言可能更快,因为np.partition由于其更复杂的算法而具有更大的开销。