在python中对大量数组进行排序的最快方法
我正在尝试用python对大量数组进行排序。我需要一次对1100多万个数组执行排序 另外,如果我可以直接获得对数组排序的索引,那就太好了 这就是为什么,到目前为止,我使用的是numpy.argsort(),但这在我的机器上太慢了(运行需要一个多小时) 在同一台机器上,R中的相同操作大约需要15分钟 有谁能告诉我用Python做这件事的更快的方法吗 谢谢 编辑: 添加一个示例 如果我有以下数据帧:在python中对大量数组进行排序的最快方法,python,performance,sorting,numpy,pandas,Python,Performance,Sorting,Numpy,Pandas,我正在尝试用python对大量数组进行排序。我需要一次对1100多万个数组执行排序 另外,如果我可以直接获得对数组排序的索引,那就太好了 这就是为什么,到目前为止,我使用的是numpy.argsort(),但这在我的机器上太慢了(运行需要一个多小时) 在同一台机器上,R中的相同操作大约需要15分钟 有谁能告诉我用Python做这件事的更快的方法吗 谢谢 编辑: 添加一个示例 如果我有以下数据帧: agg: x y w z 1 2
agg:
x y w z
1 2 2 5
1 2 6 7
3 4 3 3
5 4 7 8
3 4 2 5
5 9 9 9
我正在对其运行以下函数和命令:
def fucntion(group):
z = group['z'].values
w = group['w'].values
func = w[np.argsort(z)[::-1]][:7] #i need top 7 in case there are many
return np.array_str(func)[1:-1]
output = agg.groupby(['x,'y']).apply(function).reset_index()
因此,我的输出数据帧将如下所示:
output:
x y w
1 2 6,2
3 4 2,3
5 4 7
5 9 9
python比R慢得多的原因是python没有类型转换变量(即int、string、float),因此在确定哪个值更大的每次比较中,都会花费一部分时间来确定变量类型 您不能单独使用python来解决这个问题,但可以使用cython包含类型定义(ctypes和psyco也可以执行相同的功能,但我更喜欢cython)。一个简单的例子说明了这是如何工作的
Cython编译python文件的.c版本,可以导入该文件而不是.py,以减少运行时。使用cython编译的所有可能方法都显示在上,您的输入和输出有点混乱。请提供一些样本数据 但请注意:
熊猫排序是尽可能优化的。将重点放在序列排序上,因为数据帧的每一列都更准确地表示为一个序列。对于像您对部分排序索引感兴趣的情况,有以下几种情况 你有麻烦的
np.argsort
在:w[np.argsort(z)[::-1][:7]
,它本质上是w[idx]
,其中idx=np.argsort(z)[::-1][:7]
因此,idx
可以用np.argpartition
计算,如下所示-
idx = np.argpartition(-z,np.arange(7))[:7]
需要-z
,因为默认情况下np.argpartition
尝试按升序获取排序索引。所以,为了逆转它,我们否定了元素
因此,提议对原《守则》进行的修改如下:
func = w[np.argpartition(-z,np.arange(7))[:7]]
运行时测试-
In [162]: z = np.random.randint(0,10000000,(1100000)) # Random int array
In [163]: idx1 = np.argsort(z)[::-1][:7]
...: idx2 = np.argpartition(-z,np.arange(7))[:7]
...:
In [164]: np.allclose(idx1,idx2) # Verify results
Out[164]: True
In [165]: %timeit np.argsort(z)[::-1][:7]
1 loops, best of 3: 264 ms per loop
In [166]: %timeit np.argpartition(-z,np.arange(7))[:7]
10 loops, best of 3: 36.5 ms per loop
你到底有什么作为输入?它是数组列表吗?您可以添加一个示例输入案例吗?它是pandas数据框的一列的一部分。除了您已经尝试过的内容之外,您可以提供一些示例数据和所需的输出吗?您是否知道
argsort
的axis
参数?不,我不知道@用户2357112。我读到这篇文章,我真的不认为它能帮我完成任务。你似乎忽视或忽略了提问者使用NumPy的事实。NumPy和R需要彼此进行相似数量的类型检查;两者在排序时只需检查数组的元素类型一次,而不是每次比较都检查一次。我已经对其进行了进一步编辑。请告诉我现在是否清楚。冈扬,你想在这里做什么?你能口头解释一下你想要它做什么吗。这个例子是没有意义的,如果没有解释你想要什么,那么问题的解决方案就局限于你的代码。这是一个很好的解决方案,但是如果在我的数据帧中的某个地方,要排序的数字小于7,那么我想这是行不通的。(这是可能的。输出最多需要7)@gunjandwan那么,用这个数字替换这里的7
?你可以把它作为一个变量,让变量来处理它?类似于n=5;func=w[np.argpartition(-z,np.arange(n))[:n]]
,其中n
是该变量。@gunjandwan或您是说z
本身可能小于7个元素?是的。z本身可以小于7。但是我在len(z)上添加了一个变量。我正在我的数据集上运行它。我希望它运行得更快。@gunjandwan是的,这就是我要建议的,使用n=min(len(z),7)
然后func=w[np.argpartition(-z,np.arange(n))[:n]
。我也希望看到您的终端的运行时结果!随时通知我。