Numpy 排序和排序的复杂性差异?
我试图理解numpy数组索引的复杂性 给定一个一维numpy数组Numpy 排序和排序的复杂性差异?,numpy,time-complexity,Numpy,Time Complexity,我试图理解numpy数组索引的复杂性 给定一个一维numpy数组a。和b=numpy.argsort(A) np.sort(A)vsA[b]在时间复杂度上有什么区别 对于np.sort(A),它将是O(n log(n)),而A[b]应该是O(n)?在引擎盖下argsort进行排序,这再次给了复杂性O(n log(n))。 实际上,您可以指定算法 总而言之,虽然只有A[b]是线性的,但你不能用它来克服排序的一般复杂性,因为你还必须确定b(通过排序)。在引擎盖下argsort进行排序,这再次给出了复
a
。和b=numpy.argsort(A)
np.sort(A)
vsA[b]
在时间复杂度上有什么区别
对于
np.sort(A)
,它将是O(n log(n))
,而A[b]
应该是O(n)
?在引擎盖下argsort
进行排序,这再次给了复杂性O(n log(n))
。
实际上,您可以指定算法
总而言之,虽然只有
A[b]
是线性的,但你不能用它来克服排序的一般复杂性,因为你还必须确定b
(通过排序)。在引擎盖下argsort
进行排序,这再次给出了复杂性O(n log(n))
。
实际上,您可以指定算法
总之,虽然只有A[b]
是线性的,但你不能用它来克服排序的一般复杂性,因为你还必须确定b
(通过排序)。做一个简单的计时:
In [233]: x = np.random.random(100000)
In [234]: timeit np.sort(x)
6.79 ms ± 21 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [235]: timeit x[np.argsort(x)]
8.42 ms ± 220 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [236]: %%timeit b = np.argsort(x)
...: x[b]
...:
235 µs ± 694 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [237]: timeit np.argsort(x)
8.08 ms ± 15.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
只对一个大小进行计时并不会带来O的复杂性,但它揭示了不同步骤的相对重要性
如果不需要argsort
,则直接使用sort
。如果你已经有了b
使用它,而不是再次排序。做一个简单的计时:
In [233]: x = np.random.random(100000)
In [234]: timeit np.sort(x)
6.79 ms ± 21 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [235]: timeit x[np.argsort(x)]
8.42 ms ± 220 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [236]: %%timeit b = np.argsort(x)
...: x[b]
...:
235 µs ± 694 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [237]: timeit np.argsort(x)
8.08 ms ± 15.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
只对一个大小进行计时并不会带来O的复杂性,但它揭示了不同步骤的相对重要性
如果不需要
argsort
,则直接使用sort
。如果您已经有了b
请使用它,而不是再次排序。这里有一个直观的比较,可以更好地查看它:
#sort
def m1(A,b):
return np.sort(A)
#compute argsort and them index
def m2(A,b):
return A[np.argsort(A)]
#index with precomputed argsort
def m3(A,b):
return A[b]
A = [np.random.rand(n) for n in [10,100,1000,10000]]
日志规模上的运行时:
以下是一个直观的对比,以便更好地查看:
#sort
def m1(A,b):
return np.sort(A)
#compute argsort and them index
def m2(A,b):
return A[np.argsort(A)]
#index with precomputed argsort
def m3(A,b):
return A[b]
A = [np.random.rand(n) for n in [10,100,1000,10000]]
日志规模上的运行时:
是的,我知道这一点,但我更感兴趣的是
A[b]
的复杂性,正如问题中所述,b
是给定的。如果空间复杂性不相关,可以在线性时间内填充C[I]=A[b[I]
。如果空间是常数,A的元素必须以某种奇特的方式交换,这可能并不简单。是的,我知道这一点,但我更感兴趣的是A[b]
的复杂性,正如问题中所述,b
已经给出。如果空间复杂性不相关,你可以在线性时间内填充C[I]=A[b[I]
。如果空间是恒定的,则A的元素必须以某种奇特的方式交换,这可能不是小事。谢谢!是的,我做了同样的事情,但我仍然需要在一些技术文档中使用大o符号来表示A[b]
,我不确定o(n)
是否正确。用较小的x
快速测试表明A[b]
大致是o(n)
。它必须将b.shape
项从A
复制到一个新的数组中,其细节隐藏在复杂的c
代码中-确定b
的大小,分配目标空间,使用c
指针索引从一个数据缓冲区复制到另一个数据缓冲区。在现实世界中,操作是时间的混合。有一个设置时间、操作时间等。因此可能是a*O(1)+b*O(n)+……
对于小型阵列,设置时间占主导地位,对于大型阵列,设置时间占主导地位,O(n)等。对于非常大的阵列,内存管理也成了一个问题。谢谢!是的,我做了同样的事情,但我仍然需要在一些技术文档中使用大o符号来表示A[b]
,我不确定o(n)
是否正确。用较小的x
快速测试表明A[b]
大致是o(n)
。它必须将b.shape
项从A
复制到一个新的数组中,其细节隐藏在复杂的c
代码中-确定b
的大小,分配目标空间,使用c
指针索引从一个数据缓冲区复制到另一个数据缓冲区。在现实世界中,操作是时间的混合。有一个设置时间、操作时间等。因此可能是a*O(1)+b*O(n)+……
对于小型阵列,设置时间占主导地位,对于大型阵列,设置时间占主导地位,O(n)等。同样对于非常大的阵列,内存管理也成为一个问题。