- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 Numba 在 python 中实现最快的 jaccard 距离版本
@nb.jit()
def nbjaccard(seq1, seq2):
set1, set2 = set(seq1), set(seq2)
return 1 - len(set1 & set2) / float(len(set1 | set2))
def jaccard(seq1, seq2):
set1, set2 = set(seq1), set(seq2)
return 1 - len(set1 & set2) / float(len(set1 | set2))
%%timeit
nbjaccard("compare this string","compare a different string")
--12.4 毫秒
%%timeit
jaccard("compare this string","compare a different string")
--3.87 毫秒
为什么 numba 版本需要更长的时间?有什么方法可以加速吗?
最佳答案
在我看来,允许纯对象模式 numba 函数是一个设计错误(或者如果 numba 意识到整个函数使用 python 对象则没有警告)——因为这些是通常比纯 Python 函数慢一点。
Numba 非常强大(类型分派(dispatch)和您可以在没有类型声明的情况下编写 python 代码 - 与 C 扩展或 Cython 相比 - 真的很棒)但只有当它支持操作时:
这意味着“nopython”模式不支持任何未在此处列出的操作。如果 numba 必须退回到 "object mode"然后小心:
object mode
A Numba compilation mode that generates code that handles all values as Python objects and uses the Python C API to perform all operations on those objects. Code compiled in object mode will often run no faster than Python interpreted code, unless the Numba compiler can take advantage of loop-jitting.
这正是您的情况:您纯粹在对象模式下操作:
>>> nbjaccard.inspect_types()
[...]
# --- LINE 3 ---
# seq1 = arg(0, name=seq1) :: pyobject
# seq2 = arg(1, name=seq2) :: pyobject
# $0.1 = global(set: <class 'set'>) :: pyobject
# $0.3 = call $0.1(seq1) :: pyobject
# $0.4 = global(set: <class 'set'>) :: pyobject
# $0.6 = call $0.4(seq2) :: pyobject
# set1 = $0.3 :: pyobject
# set2 = $0.6 :: pyobject
set1, set2 = set(seq1), set(seq2)
# --- LINE 4 ---
# $const0.7 = const(int, 1) :: pyobject
# $0.8 = global(len: <built-in function len>) :: pyobject
# $0.11 = set1 & set2 :: pyobject
# $0.12 = call $0.8($0.11) :: pyobject
# $0.13 = global(float: <class 'float'>) :: pyobject
# $0.14 = global(len: <built-in function len>) :: pyobject
# $0.17 = set1 | set2 :: pyobject
# $0.18 = call $0.14($0.17) :: pyobject
# $0.19 = call $0.13($0.18) :: pyobject
# $0.20 = $0.12 / $0.19 :: pyobject
# $0.21 = $const0.7 - $0.20 :: pyobject
# $0.22 = cast(value=$0.21) :: pyobject
# return $0.22
return 1 - len(set1 & set2) / float(len(set1 | set2))
如您所见,每个操作都对 Python 对象进行操作(如每行末尾的 ::pyobject
所示)。那是因为 numba
不支持 str
和 set
。所以这里绝对没有什么比这更快的了。除非您知道如何使用 numpy 数组或同类列表(数字类型)解决此问题。
在我的电脑上,时差要大得多(使用 numba 0.32.0),但个别计时要快得多 - 微秒(10**-6
秒) 而不是 毫秒秒(10**-3
秒):
%timeit nbjaccard("compare this string","compare a different string")
10000 loops, best of 3: 84.4 µs per loop
%timeit jaccard("compare this string","compare a different string")
100000 loops, best of 3: 15.9 µs per loop
请注意 jit
默认为 lazy ,因此第一次调用应该在您为执行计时之前完成 - 因为它包括编译代码的时间。
不过,您可以进行一种优化:如果您知道两个集合的交集,则可以计算并集的长度(正如@Paul Hankin 在他的现已删除 回答中提到的):
len(union) = len(set1) + len(set2) - len(intersection)
这将导致以下(纯 python)代码:
def jaccard2(seq1, seq2):
set1, set2 = set(seq1), set(seq2)
num_intersection = len(set1 & set2)
return 1 - num_intersection / float(len(set1) + len(set2) - num_intersection)
%timeit jaccard2("compare this string","compare a different string")
100000 loops, best of 3: 13.7 µs per loop
不是更快 - 但更好。
如果您使用 cython,还有一些改进空间:
%load_ext cython
%%cython
def cyjaccard(seq1, seq2):
cdef set set1 = set(seq1)
cdef set set2 = set()
cdef Py_ssize_t length_intersect = 0
for char in seq2:
if char not in set2:
if char in set1:
length_intersect += 1
set2.add(char)
return 1 - (length_intersect / float(len(set1) + len(set2) - length_intersect))
%timeit cyjaccard("compare this string","compare a different string")
100000 loops, best of 3: 7.97 µs per loop
这里的主要优点是只需一次迭代就可以创建 set2
并计算交集中的元素数量(根本不需要创建交集)!
关于python - 使用 numba 优化 Jaccard 距离性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43596535/
A是不同元素的序列,B是A的子序列,A-B是A中的所有元素,但不是B中的所有元素距离(A) = 总和|a(i)-a(i+1)|从 i=1 到 n-1找到一个子序列 B 使得 Dist(B)+Dist(
我想通过计算每对中所有(多维)点集之间距离的平均值来量化组相似性。 我可以很容易地手动为每对组手动完成此操作,如下所示: library(dplyr) library(tibble) library(
在 OpenXML 中用于指定大小或 X、Y 坐标的度量单位是什么? (介绍)。 将那些与像素匹配是否有意义,如果是这样,那些如何转换为像素? graphicFrame.Transform = new
我想知道是否有人可以帮助我替换过渡层中的值。 如果我尝试: transitionlayer[transitionlayer >= 0.14] = 0.14 : comparison (5) is
我在 firebase 中有一个列表,其中包括地理位置(经度和纬度),并且我想获得距给定坐标最近的 10 个位置。 我正在从 MySQL 过渡,在那里我将计算 SELECT 中的距离, 并在 ORDE
如何在 Python 中根据 2 个 GPS 坐标计算速度、距离和方向(度)?每个点都有纬度、经度和时间。 我在这篇文章中找到了半正矢距离计算: Calculate distance between
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
我只想使用 matplotlib 标记两条曲线之间发生最大偏差的位置。请帮助我。 垂直距离适用于 Kolmogorov–Smirnov test import numpy as np %matplot
我有一个包含数万行重复项的文件。我想根据行号找到重复项之间的平均时间/距离。 例如:(其中第一列是行号) 1 string1 2 string2 3 string2 4 string1 5 strin
用公式speed=distance/time计算时间 但时间总是0我的输入是 distance=10 和 speed=5 我的输出必须 = 2 #include int main() { in
我正在使用 Levenshtein 算法来查找两个字符串之间的相似性。这是我正在制作的程序的一个非常重要的部分,因此它需要有效。问题是该算法没有发现以下示例相似: CONAIR AIRCON 算法给出
对于一个房地产网站,我需要实现一个允许搜索文本和距离的搜索机制。 当 lat 和 lon 记录在单独的列中时,在 MySQL 表上进行距离计算很容易,但房子往往有 LOT true/false 属性。
是否可以在触发前更改 UIPanGestureRecognizer 的距离?目前的实现似乎在触发前有 5-10 像素的距离余量,我想降低它如果可能的话。 原因是我将 UIPanGestureRecog
我试图找到两个网格之间的偏差。例如在 3d 空间中定义的两组点之间的差异,我计划使用一些 3d 可视化工具来可视化距离,例如QT3d 或一些基于开放式 gl 的库。 我有两组网格,基本上是两个 .ST
所以,我有这个函数可以快速返回两个字符串之间的 Levenshtein 距离: Function Levenshtein(ByVal string1 As String, ByVal string2
我正在尝试用字典创建一个光学字符识别系统。 事实上,我还没有实现字典=) 我听说有一些基于 Levenstein 距离的简单指标,这些指标考虑了不同符号之间的不同距离。例如。 'N' 和 'H' 彼此
我在PostGIS数据库(-4326)中使用经纬度/经度SRID。我想以一种有效的方式找到最接近给定点的点。我试图做一个 ORDER BY ST_Distance(point, ST_GeomF
我想从线串的一端开始提取沿线串已知距离处的点的坐标。 例如: library(sf) path % group_by(L1) %>% summarise(do_union =
我已经编写了这些用于聚类基于序列的数据的函数: library(TraMineR) library(cluster) clustering <- function(data){ data <- s
是否可以设置 UILabel 的行之间的距离,因为我有一个 UILabel 包含 3 行,并且换行模式是自动换行? 最佳答案 如果您指的是“前导”,它指的是类型行之间的间隙 - 您无法在 UILabe
我是一名优秀的程序员,十分优秀!