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