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

时间:2015-04-26 08:53:39

标签: python performance numpy pandas cython

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

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

每个组都可以看作是一个numpy数组,有两个整数列'col2''col3'。要了解我在做什么,您可以将每行('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版本似乎没有加速任何东西。发生了什么事?

奖金问题:您认为有更好的方法来实施此算法吗?

1 个答案:

答案 0 :(得分:1)

向量numpy测试可能是:

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

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

但是如果迭代通常一直进行,那么矢量测试将比Python迭代更快,并且比排序更快。它可能比正确编码的cython迭代慢。