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进行排序,这再次给出了复

我试图理解numpy数组索引的复杂性

给定一个一维numpy数组
a
。和
b=numpy.argsort(A)

np.sort(A)
vs
A[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)等。同样对于非常大的阵列,内存管理也成为一个问题。