Cythonizing使用numpy的函数

2024-09-19 23:55:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试对以下代码进行cythonize:

def my_func(vector_b):
    vector_b = np.unpackbits(np.frombuffer(vector_b, dtype=np.uint8))
    vector_b = (vector_b * _n_vector_ranks_only)
    min_ab = np.sum(np.minimum(vector_a, vector_b))
    max_ab = np.sum(np.maximum(vector_a, vector_b))
    return min_ab / max_ab 


_n_vector_ranks_only = np.arange(1023, -1, -1, dtype=np.uint16)

# vector_a data type is same of vector_b, is not contained in db, it is passed manually
vector_a = np.frombuffer(vector_a, dtype=np.uint8)
vector_a = (vector_a * _n_vector_ranks_only)

#fetch all vectors from DB
df = dd.read_sql_table('mydb', 'postgresql://user:passwordg@localhost/table1',  npartitions=16, index_col='id', columns=['data'])
res = df.map_partitions(lambda df: df.apply( lambda x: my_func(x['data']), axis=1), meta=('result', 'double')).compute(scheduler='processes')

#data is a binary array saved with numpy packbits

此时此刻,我正站在这一点上:

from ruzi_cython import ruzicka
def my_func(vector_b):
    vector_b = np.unpackbits(np.frombuffer(vector_b, dtype=np.uint8))
    vector_b = (vector_b * _n_vector_ranks_only)
    #min_ab = np.sum(np.minimum(vector_a, vector_b))
    #max_ab = np.sum(np.maximum(vector_a, vector_b))
    #return min_ab / max_ab 
    return ruzicka.run_old(vector_a, vector_b)

在哪里鲁齐卡.pyx这是:

# cython: profile=True
import numpy as np
cimport numpy as np
cimport cython

ctypedef np.uint16_t data_type_t

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.overflowcheck(False)
@cython.initializedcheck(False)
cdef double ruzicka_old(data_type_t[:] a, data_type_t[:] b):
    cdef int i
    cdef float max_ab = 0
    cdef float min_ab = 0
    for i in range(1024):
        if a[i] > b[i]:
            max_ab += a[i]
            min_ab += b[i]
        else:
            max_ab += b[i]
            min_ab += a[i]
    return min_ab / max_ab 

def run_old(a, b):
    return ruzicka_old(a, b)

在那里我得到了很多表演。 我仍然不能用很好的结果来计算第一部分,在这里我将两个数组相乘。你知道吗

我就是这样做乘法的:

cdef double ruzicka(data_type_16[:] a, data_type_8[:] b):
    cdef int i
    cdef float max_ab = 0
    cdef float min_ab = 0
    cdef data_type_16 tmp = 0
    for i in range(1024):
        tmp = b[i] * (1023-i)
        if a[i] > tmp:
            max_ab += a[i]
            min_ab += tmp
        else:
            max_ab += tmp
            min_ab += a[i]
    return min_ab / max_ab 

Tags: onlydatareturnabtypenpmintmp
1条回答
网友
1楼 · 发布于 2024-09-19 23:55:49

看起来您正在努力获取数组的第n位(实际上是在做np.unpackbits所做的事情)。你知道吗

第n位包含在n//8字节中(我使用的是//除法取整运算符)。您可以使用1<<m(一个位被m移位)执行“按位与”(&)访问字节中的单个位。这会给你一个数字2**(m-1),你真的只关心它是不是0。你知道吗

因此假设vector_bnp.int8_t内存视图,您可以执行以下操作:

byte_idx = n//8
bit_idx = n%8 # remainder operator
bitmask = 1<<bit_idx
bit_is_true = 1 if (vector_b[byte_idx]&bitmask) else 0

你需要把它放在一个循环中,cdef变量的类型。你知道吗

相关问题 更多 >