以下是我的cython代碼,目的是做一個bootstrap。Cython沒有速度收益嗎?
def boots(int trial, np.ndarray[double, ndim=2] empirical, np.ndarray[double, ndim=2] expected):
cdef int length = len(empirical)
cdef np.ndarray[double, ndim=2] ret = np.empty((trial, 100))
cdef np.ndarray[long] choices
cdef np.ndarray[double] m
cdef np.ndarray[double] n
cdef long o
cdef int i
cdef int j
for i in range(trial):
choices = np.random.randint(0, length, length)
m = np.zeros(100)
n = np.zeros(100)
for j in range(length):
o = choices[j]
m.__iadd__(empirical[o])
n.__iadd__(expected[o])
empirical_boot = m/length
expected_boot = n/length
ret[i] = empirical_boot/expected_boot - 1
ret.sort(axis=0)
return ret[int(trial * 0.025)].reshape((10,10)), ret[int(trial * 0.975)].reshape((10,10))
# test code
empirical = np.ones((40000, 100))
expected = np.ones((40000, 100))
%prun -l 10 boots(100, empirical,expected)
花式索引需要11秒鐘的時間,不管我在cython中調整的方式如何都保持不變。
np.random.randint(0, 40000, 40000)
需要1毫秒,所以100x需要0.1秒。
np.sort(np.ones((40000, 100))
需要0.2s。
因此,我覺得必須有方法來改進boots
。
爲什麼'cdef length = len(經驗型)'而不是'cdef int length = len(經驗型)'? – hivert
@hivert錯字,但它不會影響速度。我很驚訝它編譯。 – colinfang
以及爲什麼你使用2 100個元素向量('m'和'n'),如果它們的元素都是相同的? '__iadd__'應該在整個陣列上運行... – goncalopp