使用 Cython 定义自定义 pandas 聚合函数

Defining a custom pandas aggregation function using Cython

我在 pandas 中有一个很大的 DataFrame,包含三列:'col1' 是字符串,'col2''col3'numpy.int64。我需要做一个 groupby,然后使用 apply 应用自定义聚合函数,如下所示:

pd = pandas.read_csv(...)
groups = pd.groupby('col1').apply(my_custom_function)

每个组都可以看作是一个带有两个整数列 'col2''col3' 的 numpy 数组。要理解我在做什么,您可以将每一行 ('col2','col3') 视为一个时间间隔;我正在检查是否没有相交的间隔。我首先按第一列对数组进行排序,然后测试索引 i 处的第二列值是否小于 index i + 1.

处的第一列值

第一个问题:我的想法是使用Cython 来定义自定义聚合函数。这是个好主意吗?

我在 .pyx 文件中尝试了以下定义:

cimport nump as c_np

def c_my_custom_function(my_group_df):
    cdef Py_ssize_t l = len(my_group_df.index)
    if l < 2:
        return False

    cdef c_np.int64_t[:, :] temp_array
    temp_array = my_group_df[['col2','col3']].sort(columns='col2').values
    cdef Py_ssize_t i

    for i in range(l - 1):
        if temp_array[i, 1] > temp_array[i + 1, 0]:
            return True
    return False

我也定义了一个纯版本Python/pandas:

def my_custom_function(my_group_df):
    l = len(my_group_df.index)
    if l < 2:
        return False

    temp_array = my_group_df[['col2', 'col3']].sort(columns='col2').values

    for i in range(l - 1):
        if temp_array[i, 1] > temp_array[i + 1, 0]:
            return True
    return False

第二个问题:我对两个版本进行了计时,两者的时间完全相同。 Cython 版本似乎没有加快任何速度。发生了什么事?

奖金问题:你有没有更好的方法来实现这个算法?

矢量 numpy 测试可以是:

np.any(temp_array[:-1,1]>temp_array[1:,0])

它是否优于 python 或 cython 迭代取决于 True 发生的位置(如果有的话)。如果 return 处于迭代的早期步骤,则迭代显然更好。 cython 版本不会有太大的优势。此外,测试步骤将比排序步骤快。

但是如果迭代通常是一路走下去,那么向量测试会比Python迭代快,也比排序快。它可能比正确编码的 cython 迭代慢。