0

データは、2500の測定の時系列を含むマトリックスです。スパイクの周りに記録されたデータポイントを破棄して、各時系列を経時的に平均化する必要があります(tspike-dt * 10 ... tspike + 10 * dtの間隔で)。スパイク時間の数はニューロンごとに可変であり、2500エントリの辞書に保存されます。私の現在のコードはニューロンとスパイク時間を繰り返し、マスクされた値をNaNに設定します。次に、bottleneck.nanmean()が呼び出されます。ただし、このコードは現在のバージョンでは遅くなります。より高速な解決策があるのではないかと思います。ありがとう!

import bottleneck
import numpy as np
from numpy.random import rand, randint

t = 1
dt = 1e-4
N = 2500
dtbin = 10*dt

data = np.float32(ones((N, t/dt)))
times = np.arange(0,t,dt)
spiketimes = dict.fromkeys(np.arange(N))
for key in spiketimes:
  spiketimes[key] = rand(randint(100))

means = np.empty(N)

for i in range(N):        
  spike_times = spiketimes[i]
  datarow = data[i]
  if len(spike_times) > 0:
    for spike_time in spike_times:                        
      start=max(spike_time-dtbin,0)
      end=min(spike_time+dtbin,t)
      idx = np.all([times>=start,times<=end],0)
      datarow[idx] = np.NaN
  means[i] = bottleneck.nanmean(datarow)
4

2 に答える 2

0

コードの処理時間の大部分は、次の行から発生します。

idx = np.all([times>=start,times<=end],0)

これは、スパイクごとに、すべての値を開始と終了に対して時間で比較しているためです。この例では時間ステップが均一であるため(これはデータにも当てはまると思います)、開始インデックスと終了インデックスを単純に計算する方がはるかに高速です。

# This replaces the last loop in your example:
for i in range(N):        
    spike_times = spiketimes[i]
    datarow = data[i]
    if len(spike_times) > 0:
        for spike_time in spike_times:
            start=max(spike_time-dtbin,0)
            end=min(spike_time+dtbin,t)
            #idx = np.all([times>=start,times<=end],0)
            #datarow[idx] = np.NaN
            datarow[int(start/dt):int(end/dt)] = np.NaN
    ## replaced this with equivalent for testing
    means[i] = datarow[~np.isnan(datarow)].mean()  

これにより、実行時間が約100秒から約1.5秒に短縮されます。また、spike_timesでループをベクトル化することにより、もう少し時間を短縮することもできます。この効果は、データの特性によって異なります(スパイク率が高い場合に最も効果的です)。

kernel = np.ones(20, dtype=bool)
for i in range(N):        
    spike_times = spiketimes[i]
    datarow = data[i]
    mask = np.zeros(len(datarow), dtype=bool)
    indexes = (spike_times / dt).astype(int)
    mask[indexes] = True  
    mask = np.convolve(mask, kernel)[10:-9]

    means[i] = datarow[~mask].mean()
于 2012-08-04T20:52:35.537 に答える
0

を使用する代わりに、nanmean必要な値にインデックスを付けて使用することができますmean

means[i] = data[ (times<start) | (times>end) ].mean()

私が誤解していて、インデックス作成が必要な場合は、試してみてください

means[i] = data[numpy.logical_not( np.all([times>=start,times<=end],0) )].mean()

また、おそらく使用したくないコードではif len(spike_times) > 0(各反復でスパイク時間を削除すると仮定します。そうしないと、そのステートメントは常に true になり、無限ループが発生します)、 のみを使用しますfor spike_time in spike_times

于 2012-08-03T19:28:21.020 に答える