我不禁要问,是否有有效的算法来计算大量的惯性阵列之间的配对数量。 Cython。
match_ints.pyx
cimport cython
from libc.stdlib cimport calloc, free
import numpy as np
cimport numpy as np
np.import_array()
@cython.wraparound(False)
@cython.boundscheck(False)
@cython.initializedcheck(False)
cdef void count_matches(int[:, ::1] target_arrays, int[::1] ref_array, int[::1] num_matches):
cdef:
Py_ssize_t i, j
Py_ssize_t n = target_arrays.shape[0]
Py_ssize_t c = target_arrays.shape[1]
Py_ssize_t nf = ref_array.shape[0]
Py_ssize_t m = ref_array[nf - 1] + 5
int * ind = <int *> calloc(m, sizeof(int))
int k, g
for i in range(nf):
ind[ref_array[i]] = 1
for i in range(n):
k = 0
for j in range(c):
g = target_arrays[i, j]
if g < m and ind[g] == 1:
k += 1
num_matches[i] = k
free(ind)
cpdef count_num_matches(int[:, ::1] target_arrays, int[::1] ref_array):
cdef:
Py_ssize_t n = target_arrays.shape[0]
int[::1] num_matches = np.zeros(n, dtype=np.int32)
count_matches(target_arrays, ref_array, num_matches)
return np.asarray(num_matches)
这里的想法非常简单。 为与参考分类阵列相匹配,按加标顺序排列(sort
方法)。 设定指标阵列ind
,其长度为参照阵列的最大体积(+5
),以避免在范围上形成指数化,同时利用阵列中的惯性并不大。 因此,每一分类都被视为一种指数,在<编码>ind中的相应职位被定为1。 然后通过每一条<代码>具体目标——信息代码”进行计算,以计算在参考阵列中的分类账数目。
在配对期间,如果<条码>内d条码>中的索引>为<1>> /代码>,则所有在<条码>上的分类账号均视为索引和配对。
测试方法载于test_main_counts.py
。
# test_main_counts.py
from match_ints import count_num_matches
import numpy as np
def count_num_matches_main():
x = np.random.randint(50, 6000, size=(1000000, 40), dtype=np.int32)
ref_x = np.random.randint(100, 2500, size=800, dtype=np.int32)
ref_x.sort()
return count_num_matches(x, ref_x)
if __name__ == "__main__":
nums = count_num_matches_main()
print(nums[:10])
The setup
file.
from setuptools import setup
from Cython.Build import cythonize
import numpy as np
setup(
ext_modules=cythonize(
"match_ints.pyx",
compiler_directives={
"language_level": "3",
}
),
include_dirs=[
np.get_include()
]
)
由于所有分类账都不算大,而且有许多重复(在我的实际应用中,数百万阵列仅包含几千个独特的分类账),因此,任何相关的算法都是为了通过利用不太独特的分类来改善这类问题?