25

ここにCを使用してカスタムnumpydtypeを作成する例があります:

さらに、cythonでカスタムufuncを作成することは可能のようです。

cythonを使用してdtypeを作成することも可能であるようです(そして、そのためのカスタムufuncを作成します)。出来ますか?もしそうなら、あなたは例を投稿できますか?

使用事例:

生存分析をしたいです。基本的なデータ要素は、関連する打ち切り値を持つ生存時間(フロート)です(関連する時間が失敗時間を表す場合はFalse、代わりに打ち切り時間を表す場合はTrue(つまり、観測期間中に障害が発生しなかった場合))。

明らかに、これらの値を格納するために2つのnumpy配列を使用することができます。時間のfloat配列と、censor値のbool配列です。ただし、イベントが複数回発生する可能性について説明したいと思います(これは、たとえば心臓発作の良いモデルです。複数発生する可能性があります)。この場合、MultiEventsと呼ぶオブジェクトの配列が必要です。それぞれMultiEventに一連のフロート(無修正の障害時間)と観測期間(フロートも)が含まれています。失敗の数はすべてので同じではないことに注意してくださいMultiEvent

MultiEventsの配列に対していくつかの操作を実行できる必要があります。

  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_vecとの寸法にh_vec互換性がある 限り機能します。

私の現在の実装ではを使用していnumpy.vectorizeます。これは1と2には十分に機能しますが、3には遅すぎます。MultiDataオブジェクトの障害の数が事前にわからないため、これを実行できないことにも注意してください。

4

2 に答える 2

1

Numpy 配列は、固定サイズのデータ​​型に最適です。配列内のオブジェクトのサイズが固定されていない場合 (MultiEvent など)、操作が大幅に遅くなる可能性があります。

event_id、time、period の 3 つのフィールドを持つ 1 次元線形レコード配列にすべての生存時間を格納することをお勧めします。各イベントは、配列内で複数回出現する可能性があります。

>>> 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)]))
    <...>
于 2012-11-11T16:32:12.163 に答える
0

質問に直接答えなかったことをお詫びしますが、以前にも同様の問題がありました。正しく理解できれば、あなたが今抱えている本当の問題は可変長データを持っていることです。 numpy の強みであり、パフォーマンスの問題が発生している理由です。マルチイベントのエントリの最大数を前もって知っていない限り、問題が発生し、マルチ イベントではないイベントのためにゼロで埋められたメモリ/ディスク スペースの負荷を浪費することになります。

複数のフィールドを持つデータ ポイントがあり、その一部は他のフィールドに関連しており、一部はグループで識別する必要があります。これは、パフォーマンス、メモリ、ディスク上のスペース、および健全性の理由から、この情報を格納するための何らかの形式のデータベースを検討する必要があることを強く示唆しています。

あなたのコードに慣れていない人にとっては、単純なデータベース スキーマを理解する方が、イライラするほど遅くて肥大化する複雑でハッキングされた numpy 構造よりもはるかに簡単です。それに比べて、SQL クエリはすばやく簡単に記述できます。

Event および MultiEvent テーブルを持つ説明の理解に基づいて、各 Event エントリが関連する MultiEvent テーブルへの外部キーを持っていることをお勧めします。

于 2012-11-09T06:26:04.600 に答える