如何使用cython创建自定义numpy dtype

这里有一些使用C创建自定义numpy dtypes的例子:

另外,它似乎可以在cython中创建自定义的ufuncs:

它似乎也应该可以使用cython创建一个dtype(然后为它创建自定义的ufuncs)。 可能吗? 如果是这样,你可以发布一个例子吗?

使用案例:

我想做一些生存分析。 基本数据元素是具有相关传感器值的生存时间(浮点数)(如果相关时间表示失败时间则为假,如果它代表截尾时间(即在观察期间未发生失败)则为真)。

很明显,我可以使用两个numpy数组来存储这些值:一个用于时间的浮点数组和一个用于检查值的布尔数组。 但是,我想说明多次发生事件的可能性(这是心脏病发作的良好模型 - 可以有多个)。 在这种情况下,我需要一个称为MultiEvent的对象数组。 每个MultiEvent包含一系列浮点数(未经审查的失败次数)和观察期(也是浮点数)。 请注意,所有MultiEvent的失败次数并不相同。

我需要能够对MultiEvent的数组执行一些操作:

  • 获取每个故障的数量

  • 获取审查时间(即观察期减去所有失败次数的总和)

  • 根据附加的参数数组(例如一组危害值)计算对数似然值。 例如,单个MultiEvent M和常数危险值h对数似然性可能类似于:

    sum(log(h) + h*t for t in M.times) - h*(M.period - sum(M.times))

  • 其中M.times是失败次数的列表(数组,无论),而M.period是总观察期。 我想要适用适当的numpy广播规则,以便我可以做到:

    log_lik = logp(M_vec,h_vec)
    

    只要M_vech_vec的尺寸一致,它就会工作。

    我目前的实现使用numpy.vectorize 。 这对于1和2来说已经足够好了,但对于3来说速度太慢了。请注意,我不能这样做,因为我的MultiData对象中的失败次数未知。


    Numpy数组最适合于固定大小的数据类型。 如果数组中的对象不是固定大小的(例如MultiEvent),则操作可能会变得更慢。

    我建议你将所有的生存时间存储在带有3个字段的1d线性记录数组中:event_id,time,period。 每个事件可以在数组中出现多次:

    >>> import numpy as np
    >>> rawdata = [(1, 0.4, 4), (1, 0.6, 6), (2,2.6, 6)]
    >>> npdata = np.rec.fromrecords(rawdata, names='event_id,time,period')
    >>> print npdata
    [(1, 0.40000000000000002, 4) (1, 0.59999999999999998, 6) (2, 2.6000000000000001, 6)]
    

    要获取特定索引的数据,您可以使用奇特的索引:

    >>> eventdata = npdata[npdata.event_id==1]
    >>> print eventdata
    [(1, 0.40000000000000002, 4) (1, 0.59999999999999998, 6)]
    

    这种方法的优点是可以轻松地将它与基于ndarray的函数进行整合。 您也可以按照手册中的描述从cython访问这些数组:

    cdef packed struct Event:
        np.int32_t event_id
        np.float64_t time
        np.float64_6 period
    
    def f():
        cdef np.ndarray[Event] b = np.zeros(10,
            dtype=np.dtype([('event_id', np.int32),
                            ('time', np.float64),
                            ('period', np.float64)]))
        <...>
    

    我很抱歉没有直接回答这个问题,但之前我遇到过类似的问题,如果我理解正确,那么现在你遇到的真正问题是你有可变长度的数据,这实际上不是真正的问题之一numpy的优势,也是你遇到性能问题的原因。 除非事先知道多重事件的最大条目数,否则您将遇到问题,即使这样,您将浪费大量内存/磁盘空间,以填充不是多事件的事件的零。

    您有多个字段的数据点,其中一些与其他字段相关,其中一些需要以组的形式进行标识。 这强烈暗示你应该考虑一个存储这些信息的表单的数据库,用于性能,内存,磁盘空间和理智的原因。

    对于一个刚接触你的代码的人来说,理解一个简单的数据库模式要比一个复杂的,黑客入侵的结构要容易得多,而这个结构会令人沮丧地变得缓慢和臃肿。 SQL查询比较快速且易于编写。

    我建议根据我对您的解释的理解,其中包含Event和MultiEvent表,其中每个Event条目都有一个与MultiEvent表相关的外键。

    链接地址: http://www.djcxy.com/p/62923.html

    上一篇: How to create a custom numpy dtype using cython

    下一篇: cython memoryview slower than expected