numpy
有一个gcd
函数在其模块结构的某处吗?Numpy gcd功能
我知道fractions.gcd
,但认为numpy
相当于可能更快,并与numpy
数据类型更好地工作。
我一直无法发现谷歌以外的任何东西,而不是这个link这似乎过时了,我不知道我将如何访问它建议存在的_gcd
函数。
天真尝试:
np.gcd
np.euclid
并没有为我工作...
numpy
有一个gcd
函数在其模块结构的某处吗?Numpy gcd功能
我知道fractions.gcd
,但认为numpy
相当于可能更快,并与numpy
数据类型更好地工作。
我一直无法发现谷歌以外的任何东西,而不是这个link这似乎过时了,我不知道我将如何访问它建议存在的_gcd
函数。
天真尝试:
np.gcd
np.euclid
并没有为我工作...
你可以把它写自己:
def numpy_gcd(a, b):
a, b = np.broadcast_arrays(a, b)
a = a.copy()
b = b.copy()
pos = np.nonzero(b)[0]
while len(pos) > 0:
b2 = b[pos]
a[pos], b[pos] = b2, a[pos] % b2
pos = pos[b[pos]!=0]
return a
以下是测试结果和速度的代码:
In [181]:
n = 2000
a = np.random.randint(100, 1000, n)
b = np.random.randint(1, 100, n)
al = a.tolist()
bl = b.tolist()
cl = zip(al, bl)
from fractions import gcd
g1 = numpy_gcd(a, b)
g2 = [gcd(x, y) for x, y in cl]
print np.all(g1 == g2)
True
In [182]:
%timeit numpy_gcd(a, b)
1000 loops, best of 3: 721 us per loop
In [183]:
%timeit [gcd(x, y) for x, y in cl]
1000 loops, best of 3: 1.64 ms per loop
两个和你的numpy版本更快一点点 – bph 2013-03-22 13:07:36
你写的函数不适用于numpy_gcd(10,5)还是我做错了什么?我得到0-d数组无法索引 – evan54 2014-04-15 21:14:52
它是因为函数期望numpy数组(可能是numpy标量)。您应该可以执行numpy_gcd [10],[5])或修改该函数以直接与Python标量一起工作。 – coderforlife 2015-04-22 05:07:29
似乎没有gcd
功能尚未在numpy
。但是,有一个gcd function in fractions module。如果您需要在numpy
阵列进行gcd
,你可以用它建立一个ufunc
:
gcd = numpy.frompyfunc(fractions.gcd, 2, 1)
我很惊讶numpy不包含gcd功能 – bph 2013-03-22 11:59:14
不错。要获取整个列表的gcd,可以使用'numpy.ufunc.reduce(gcd,m)',其中'm'是列表,'gcd'就是这个答案中定义的。 – 2017-06-06 13:27:17
公共服务公告的使用Python 3.5
人from math import gcd
gcd(2, 4)
如果你想自己动手写一个班轮:
def gcd(a: int, b: int): return gcd(b, a % b) if b else a
万一期望的结果是不是各个元素的最大公约数,而是所有数字的数组中的GCD,你可能会使用下面的代码。
import numpy as np
from math import gcd as mathgcd
def numpy_set_gcd(a):
a = np.unique(a)
if not a.dtype == np.int or a[0] <= 0:
raise ValueError("Argument must be an array of positive " +
"integers.")
gcd = a[0]
for i in a[1:]:
gcd = mathgcd(i, gcd)
if gcd == 1:
return 1
return gcd
根据使用情况下,它可以更快省略分选步骤a = np.unique(a)
。
另一种(也许更优雅,但更慢)的实现使用ufuncs是
import numpy as np
from math import gcd as mathgcd
npmathgcd = np.frompyfunc(mathgcd, 2, 1)
def numpy_set_gcd2(a):
a = np.unique(a)
if not a.dtype == np.int or a[0] <= 0:
raise ValueError("Argument must be an array of positive " +
"integers.")
npmathgcd.at(a[1:], np.arange(a.size-1), a[:-1])
return a[-1]
我觉得'你在谈论_gcd'功能是'numpy.core._internal._gcd',但它在纯Python(所以不要太快),并且在任何情况下都不处理numpy数组。 – DSM 2013-03-22 11:43:50
是使用fractions.gcd的事实上的方法吗?我假设这将是一个更快的C实现 – bph 2013-03-22 11:45:15