如何创建自定义使用用Cython numpy的D型(How to create a custom n

2019-07-03 13:15发布

有创建用C定制numpy的dtypes例子在这里 :

此外,它似乎是可能在用Cython创建自定义ufuncs:

现在看来似乎也应该可以创建一个使用D型用Cython(然后为它创建自定义ufuncs)。 可能吗? 如果是这样,你可以发布一个例子吗?

使用案例:

我想要做一些生存分析。 基本数据元素是存活时间(浮点)相关联检查员值(如果相关的时间表示失败时间假和True,如果它不是代表一个截尾时间(即,在观察期间)没有发生故障)。

很显然,我可以只使用两个numpy的阵列来存储这些值:float数组的时间和一个布尔数组御史值。 不过,我想解释发生多次的事件的可能性(这是,比如说,心脏发作了良好的模型 - 你可以有多个)。 在这种情况下,我需要我称之为对象的数组MultiEvent秒。 每个MultiEvent包含漂浮的序列(未经审查失败次)和观察周期(也浮子)。 请注意,失败的次数是不是都是一样的MultiEvent秒。

我需要能够到的磁盘阵列上执行一些操作MultiEvent S:

  1. 获得每个失败的次数

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

  3. 计算基于的参数额外的阵列(如危险值的阵列)对数似然。 例如,对于一个单一的对数似然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.另请注意,我不能做这个 ,因为失败的我多数据对象数量不提前知道。

Answer 1:

numpy的阵列是最适合的数据类型与固定大小。 如果数组中的对象是不固定的尺寸(如您的MultiEvent)的操作会变得慢得多。

我建议你所有的存活时间的存储在一个一维线性记录阵列有3个字段:事项标识,时间,期限。 每个事件可出现在阵列中复式倍:

>>> 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,功能分类:G642.44它。 您还可以用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)]))
    <...>


Answer 2:

我不直接回答这个问题道歉,但我以前也有类似的问题,如果我理解正确的话,你现在遇到的真正的问题是,你有可变长度的数据,这是真的,真的的不是一个numpy的的优势,是你正在运行到性能问题的原因。 除非你事先知道一个multievent条目的最大数量,你就会有问题,即使这样会浪费你的内存/磁盘空间的负载以零填充对于那些不支持多活动活动。

你有个数据点与多个领域,其中一些涉及到其他领域,其中一些需要在组被识别。 这强烈暗示,你应该考虑某种形式的数据库,用于存储这些信息,对性能,内存空间的磁盘上和理智的原因。

这将是新的人更容易在你的代码来了解一个简单的数据库模式比一个复杂,黑客-ON-numpy的结构,这将是令人沮丧的缓慢和臃肿。 SQL查询是快速和容易的比较来写。

我会根据我的有事件和MultiEvent表,其中每个事件条目都有相关的外键进入MultiEvent表,其中你的解释理解建议。



文章来源: How to create a custom numpy dtype using cython