Numpy gcd function

前端 未结 5 1923
萌比男神i
萌比男神i 2020-12-19 01:44

Does numpy have a gcd function somewhere in its structure of modules?

I\'m aware of fractions.gcd but thought a numpy

相关标签:
5条回答
  • 2020-12-19 01:56

    You can write it yourself:

    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
    

    Here is the code to test the result and speed:

    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
    
    0 讨论(0)
  • 2020-12-19 02:08

    Public service announcement for anyone using Python 3.5

    from math import gcd
    gcd(2, 4)
    

    And if you want to write it yourself in a one-liner:

    def gcd(a: int, b: int): return gcd(b, a % b) if b else a
    
    0 讨论(0)
  • 2020-12-19 02:10

    In case the desired result is not an element-wise gcd but rather the gcd of all numbers in the array, you may use the code below.

    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
    

    Depending on the use case, it can be faster to omit the sorting step a = np.unique(a).

    An alternative (maybe more elegant but slower) implementation using ufuncs is

    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]
    
    0 讨论(0)
  • 2020-12-19 02:14

    The functions gcd (Greatest Common Divisor) and lcm (Lowest Common Multiple) have been added to numpy in version 1.15.

    0 讨论(0)
  • 2020-12-19 02:18

    It seems there is no gcd function yet in numpy. However, there is a gcd function in fractions module. If you need to perform gcd on numpy arrays, you could build a ufunc using it:

    gcd = numpy.frompyfunc(fractions.gcd, 2, 1)
    
    0 讨论(0)
提交回复
热议问题