我想在Python中实现优势点树,但是它使用C++中的STD::NthyCype元素。在
所以我想在Python或numpy中找到等价的“nth_element”函数。在
注意,第N个元素只对数组进行偏序,它是O(N)。在int the_array[10] = {4,5,7,3,6,0,1,2,9,8};
std::vector the_v(the_array,the_array+10);
std::nth_element (the_v.begin()+0, the_v.begin()+5, the_v.begin()+10);
现在向量可以是:
^{pr2}$
我不仅要得到第n个元素,还要重新排列列表的两个部分,[3,0,2,1,4]和[6,7,9,8]。在
此外,nth_element support接受一个可以比较这两个元素的函数,例如,在下面的as中,vector是一个vector op DataPoint,DistanceComparator函数将用_v.begin()比较两个点的距离:vector the_v;
for(int n = 0; n < N; n++) the_v[n] = DataPoint(D, n, X + n * D);
std::nth_element (the_v.begin()+0, the_v.begin()+5, the_v.begin()+10,
DistanceComparator(the_v.begin()));
编辑:
我使用了bhuvan venkatesh的答案,并编写了一些代码进行测试。在partition_timer = timeit.Timer("numpy.partition(a, 10000)",
"import numpy;numpy.random.seed(2);"+
"a = numpy.random.rand(10000000)")
print(partition_timer.timeit(10))
sort_timer = timeit.Timer("numpy.sort(a)",
"import numpy;numpy.random.seed(2);"+
"a = numpy.random.rand(10000000)")
print(sort_timer.timeit(10))
sorted_timer = timeit.Timer("sorted(a)",
"import numpy;numpy.random.seed(2);"+
"a = numpy.random.rand(10000000)")
print(sorted_timer.timeit(10))
结果是:2.2217168808
17.0386350155
281.301710844
然后,我将使用C++代码做更多的测试。在
但是有一个问题,当使用numpy时,它总是返回一个新的数组,当我的数组很大时,它会浪费大量的内存。
我怎么办。
或者我只需要为Python写一个C++扩展。在
编辑2:
@bhuvan venkatesh感谢您推荐分区函数。在
我使用如下分区:import numpy
@profile
def for_numpy():
numpy.random.seed(2)
a = numpy.random.rand(1e7)
for i in range(100):
a.partition(numpy.random.randint(1e6))
if __name__ == '__main__':
for_numpy()
运行剖析器如下:python -m memory_profiler profiler_test.py
结果是:Line # Mem usage Increment Line Contents
================================================
25 23.613 MiB 0.000 MiB @profile
26 def for_numpy():
27 23.613 MiB 0.000 MiB numpy.random.seed(2)
28 99.934 MiB 76.320 MiB a = numpy.random.rand(1e7)
29 100.004 MiB 0.070 MiB for i in range(100):
30 100.004 MiB 0.000 MiB a.partition(numpy.random.randint(1e6))
它不会复制整个数组,就像:
numpy.分区(a,3)
结论:numpy.ndarray.partition是我想找的那个。在