10

在其模块结构的某处numpy有功能吗?gcd

我知道fractions.gcd但认为numpy等效的可能更快,并且可以更好地处理numpy数据类型。

除了这个似乎过时的链接之外,我无法在谷歌上发现任何东西,我不知道如何访问_gcd它建议存在的功能。

天真地尝试:

np.gcd
np.euclid

对我没用...

4

5 回答 5

12

你可以自己写:

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
于 2013-03-22T12:46:34.193 回答
11

使用 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
于 2016-10-25T23:31:16.003 回答
9

中似乎还没有gcd功能numpy但是,分数模块中有一个gcd 函数。如果您需要gcdnumpy数组上执行,您可以使用它构建一个ufunc

gcd = numpy.frompyfunc(fractions.gcd, 2, 1)
于 2013-03-22T11:50:24.820 回答
6

函数gcd (最大公约数)lcm (最小公倍数)已添加到 numpy版本 1.15

您可以在一对标量上“按原样”使用它们

import numpy as np

np.gcd(-5, 10)  # yields '5'

或在列表或数组上使用.reduce

np.gcd.reduce(np.array([-5, 10, 0, 5]))  # yields '5'
于 2018-12-06T11:50:21.603 回答
1

如果所需的结果不是按元素计算的 gcd,而是数组中所有数字的 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]
于 2017-11-02T20:12:23.800 回答