- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
使用 numpy 的快速排序对整数数组进行排序已成为我算法的瓶颈。不幸的是,numpy 没有 radix sort yet .虽然counting sort将是 numpy 中的一行:
np.repeat(np.arange(1+x.max()), np.bincount(x))
请参阅 How can I vectorize this python count sort so it is absolutely as fast as it can be? 的已接受答案问题,整数在我的应用程序中可以从 0
运行到 2**32
。
我被快速排序困住了吗?
最佳答案
不,您没有被快速排序困住。例如,您可以使用integer_sort
来自 Boost.Sort或来自 usort 的 u4_sort
.对该数组进行排序时:
array(randint(0, high=1<<32, size=10**8), uint32)
我得到以下结果:
NumPy quicksort: 8.636 s 1.0 (baseline)Boost.Sort integer_sort: 4.327 s 2.0x speedupusort u4_sort: 2.065 s 4.2x speedup
I would not jump to conclusions based on this single experiment and use usort
blindly. I would test with my actual data and measure what happens. Your mileage will vary depending on your data and on your machine. Theinteger_sort
in Boost.Sort has a rich set of options for tuning, see the documentation.
Below I describe two ways to call a native C or C++ function from Python. Despite the long description, it's fairly easy to do it.
Boost.Sort
Put these lines into the spreadsort.cpp file:
#include <cinttypes>
#include "boost/sort/spreadsort/spreadsort.hpp"
using namespace boost::sort::spreadsort;
extern "C" {
void spreadsort(std::uint32_t* begin, std::size_t len) {
integer_sort(begin, begin + len);
}
}
它基本上实例化了 32 位的模板化 integer_sort
无符号整数; extern "C"
部分通过禁用来确保 C 链接名称修改。假设您正在使用 gcc 并且必要的包含 boost 文件在/tmp/boost_1_60_0
目录下,编译即可:
g++ -O3 -std=c++11 -march=native -DNDEBUG -shared -fPIC -I/tmp/boost_1_60_0 spreadsort.cpp -o spreadsort.so
关键标志是-fPIC
来生成 position-independet code和 -shared
生成一个 shared object.so 文件。 (阅读 gcc 的文档以获取更多详细信息。)
然后,包装 spreadsort()
C++ 函数在 Python 中使用 ctypes
:
from ctypes import cdll, c_size_t, c_uint32
from numpy import uint32
from numpy.ctypeslib import ndpointer
__all__ = ['integer_sort']
# In spreadsort.cpp: void spreadsort(std::uint32_t* begin, std::size_t len)
lib = cdll.LoadLibrary('./spreadsort.so')
sort = lib.spreadsort
sort.restype = None
sort.argtypes = [ndpointer(c_uint32, flags='C_CONTIGUOUS'), c_size_t]
def integer_sort(arr):
assert arr.dtype == uint32, 'Expected uint32, got {}'.format(arr.dtype)
sort(arr, arr.size)
或者,您可以使用 cffi :
from cffi import FFI
from numpy import uint32
__all__ = ['integer_sort']
ffi = FFI()
ffi.cdef('void spreadsort(uint32_t* begin, size_t len);')
C = ffi.dlopen('./spreadsort.so')
def integer_sort(arr):
assert arr.dtype == uint32, 'Expected uint32, got {}'.format(arr.dtype)
begin = ffi.cast('uint32_t*', arr.ctypes.data)
C.spreadsort(begin, arr.size)
在 cdll.LoadLibrary()
和 ffi.dlopen()
调用中,我假设spreadsort.so
文件的路径是 ./spreadsort.so
。或者,你可以写
lib = cdll.LoadLibrary('spreadsort.so')
或
C = ffi.dlopen('spreadsort.so')
如果将 spreadsort.so
的路径附加到 LD_LIBRARY_PATH
环境多变的。另见 Shared Libraries .
用法。在这两种情况下,您只需调用上面的 Python 包装函数 integer_sort()
使用 32 位无符号整数的 numpy 数组。
排序
对于u4_sort
,可以这样编译:
cc -DBUILDING_u4_sort -I/usr/include -I./ -I../ -I../../ -I../../../ -I../../../../ -std=c99 -fgnu89-inline -O3 -g -fPIC -shared -march=native u4_sort.c -o u4_sort.so
在 u4_sort.c
文件所在的目录中发出此命令。(可能有一种不那么骇人听闻的方式,但我没能弄明白。我只是查看了 usort 目录中的 deps.mk 文件以找出必要的编译器标志和包含路径。)
然后,您可以按如下方式包装 C 函数:
from cffi import FFI
from numpy import uint32
__all__ = ['integer_sort']
ffi = FFI()
ffi.cdef('void u4_sort(unsigned* a, const long sz);')
C = ffi.dlopen('u4_sort.so')
def integer_sort(arr):
assert arr.dtype == uint32, 'Expected uint32, got {}'.format(arr.dtype)
begin = ffi.cast('unsigned*', arr.ctypes.data)
C.u4_sort(begin, arr.size)
在上面的代码中,我假设到 u4_sort.so
的路径是附加到 LD_LIBRARY_PATH
环境变量。
用法。与之前使用 Boost.Sort 一样,您只需使用 32 位无符号整数的 numpy 数组调用上述 Python 包装函数 integer_sort()
。
关于python - 如何比快速排序更快地对整数数组进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35317442/
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
从以下网站,我找到了执行java AD身份验证的代码。 http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexcepti
似乎 melt 会使用 id 列和堆叠的测量变量 reshape 您的数据框,然后通过转换让您执行聚合。 ddply,从 plyr 包看起来非常相似..你给它一个数据框,几个用于分组的列变量和一个聚合
我的问题是关于 memcached。 Facebook 使用 memcached 作为其结构化数据的缓存,以减少用户的延迟。他们在 Linux 上使用 UDP 优化了 memcached 的性能。 h
在 Camel route ,我正在使用 exec 组件通过 grep 进行 curl ,但使用 ${HOSTNAME} 的 grep 无法正常工作,下面是我的 Camel 路线。请在这方面寻求帮助。
我正在尝试执行相当复杂的查询,在其中我可以排除与特定条件集匹配的项目。这是一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我正在尝试执行相当复杂的查询,我可以在其中排除符合特定条件集的项目。这里有一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我发现了很多嵌入/内容项目的旧方法,并且我遵循了在这里找到的最新方法(我假设):https://blog.angular-university.io/angular-ng-content/ 我正在尝试
我正在寻找如何使用 fastify-nextjs 启动 fastify-cli 的建议 我曾尝试将代码简单地添加到建议的位置,但它不起作用。 'use strict' const path = req
我正在尝试将振幅 js 与 React 和 Gatsby 集成。做 gatsby developer 时一切看起来都不错,因为它发生在浏览器中,但是当我尝试 gatsby build 时,我收到以下错
我试图避免过度执行空值检查,但同时我想在需要使代码健壮的时候进行空值检查。但有时我觉得它开始变得如此防御,因为我没有实现 API。然后我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异
尝试进行包含一些 NOT 的 Kibana 搜索,但获得包含 NOT 的结果,因此猜测我的语法不正确: "chocolate" AND "milk" AND NOT "cow" AND NOT "tr
我正在使用开源代码共享包在 iOS 中进行 facebook 集成,但收到错误“FT_Load_Glyph failed: glyph 65535: error 6”。我在另一台 mac 机器上尝试了
我正在尝试估计一个标准的 tobit 模型,该模型被审查为零。 变量是 因变量 : 幸福 自变量 : 城市(芝加哥,纽约), 性别(男,女), 就业(0=失业,1=就业), 工作类型(失业,蓝色,白色
我有一个像这样的项目布局 样本/ 一种/ 源/ 主要的/ java / java 资源/ .jpg 乙/ 源/ 主要的/ java / B.java 资源/ B.jpg 构建.gradle 设置.gr
如何循环遍历数组中的多个属性以及如何使用map函数将数组中的多个属性显示到网页 import React, { Component } from 'react'; import './App.css'
我有一个 JavaScript 函数,它进行 AJAX 调用以返回一些数据,该调用是在选择列表更改事件上触发的。 我尝试了多种方法来在等待时显示加载程序,因为它当前暂停了选择列表,从客户的 Angul
可能以前问过,但找不到。 我正在用以下形式写很多语句: if (bar.getFoo() != null) { this.foo = bar.getFoo(); } 我想到了三元运算符,但我认
我有一个表单,在将其发送到 PHP 之前我正在执行一些验证 JavaScript,验证后的 JavaScript 函数会发布用户在 中输入的文本。页面底部的标签;然而,此消息显示短暂,然后消失...
我是一名优秀的程序员,十分优秀!