在Python中有效地计算事件/刺激触发的平均值

2024-05-23 21:01:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我想计算事件/刺激触发的平均计算效率。 假设我有一个signal,例如

signal = [random.random() for i in xrange(0, 1000)]

{cd2>带数据点^

^{pr2}$

我知道这个信号的采样率是

Fs = 25000 # Hz

在这种情况下,我知道信号的总时间

T_sec = n_signal / float(Fs)  

在特定的时间,某些事件会发生,例如

t_events = [0.01, 0.017, 0.018, 0.022, 0.034, 0.0345, 0.03456]

现在我想找出这些事件发生前某个时间的信号

t_bef = 0.001

直到这些事件发生后的某个时间,例如

t_aft = 0.002

一旦我得到了所有这些信号,我想平均这些。 在过去,我会创建信号的时间向量

t_signal = numpy.linspace(0, T_sec, n_signal)

并查找t_signalt_events的所有索引,例如使用numpy.serachsortedLink

因为我知道信号的采样率,所以可以更快地完成,比如

indices = [int(i * Fs) for i in t_events]

这为我节省了t_signal的内存,而且我不必遍历整个信号来找到我的索引。在

接下来,我将确定t_bef和{}对应的数据样本数量

nsamples_t_bef = int(t_bef * Fs)
nsamples_t_aft = int(t_aft * Fs)

我将把信号块保存在list

signal_chunks = list()
for i in xrange(0, len(t_events)):
    signal_chunks.append(signal[indices[i] - nsamples_t_bef : indices[i] + nsamples_t_aft])

最后我要平均这些

event_triggered_average = numpy.mean(signal_chunks, axis = 0)

如果我对时间向量感兴趣,我用

t_event_triggered_average = numpy.linspace(-t_signal[nsamples_t_bef], t_signal[nsamples_t_aft], nsamples_t_bef + nsamples_t_aft)

现在我的问题是:有没有一种计算效率更高的方法来做到这一点?如果我得到一个包含许多数据点和许多事件的信号,这个计算可能需要一段时间。list是保存这些块的最佳数据结构吗?你知道如何更快地获取数据块吗?也许用缓冲器? 提前感谢您的意见和建议。在

最小工作示例

import numpy
import random

random.seed(0)
signal = [random.random() for i in xrange(0, 1000)]

# sampling rate
Fs = 25000 # Hz

# total time of the signal
n_signal = len(signal) 
T_sec = n_signal / float(Fs)  

# time of events of interest
t_events = [0.01, 0.017, 0.018, 0.022, 0.034, 0.0345, 0.03456]

# and their corresponding indices
indices = [int(i * Fs) for i in t_events]

# define the time window of interest around each event
t_bef = 0.001
t_aft = 0.002

# and the corresponding index offset
nsamples_t_bef = int(t_bef * Fs)
nsamples_t_aft = int(t_aft * Fs)

# vector of signal times
t_signal = numpy.linspace(0, T_sec, n_signal)

signal_chunks = list()
for i in xrange(0, len(t_events)):
    signal_chunks.append(signal[indices[i] - nsamples_t_bef : indices[i] + nsamples_t_aft])

# average signal value across chunks
event_triggered_average = numpy.mean(signal_chunks, axis = 0)

# not sure what's going on here
t_event_triggered_average = numpy.linspace(-t_signal[nsamples_t_bef],
                                            t_signal[nsamples_t_aft],
                                            nsamples_t_bef + nsamples_t_aft)

Tags: innumpyforsignal信号时间randomevents
1条回答
网友
1楼 · 发布于 2024-05-23 21:01:25

由于您的信号是在一个规则的网格上定义的,所以您可以进行一些运算来找到所需的所有样本的索引。然后,可以使用单个索引操作构造包含块的数组。在

import numpy as np

# Making some test data
n_signal = 1000
signal = np.random.rand(n_signal)
Fs = 25000 # Hz
t_events = np.array([0.01, 0.017, 0.018, 0.022, 0.034, 0.0345, 0.03456])

# Preferences
t_bef = 0.001
t_aft = 0.002

# The number of samples in a chunk
nsamples = int((t_bef+t_aft) * Fs)

# Create a vector from 0 up to nsamples
sample_idx = np.arange(nsamples)

# Calculate the index of the first sample for each chunk
# Require integers, because it will be used for indexing
start_idx = ((t_events - t_bef) * Fs).astype(int)

# Use broadcasting to create an array with indices
# Each row contains consecutive indices for each chunk
idx = start_idx[:, None] + sample_idx[None, :]

# Get all the chunks using fancy indexing
signal_chunks = signal[idx]

# Calculate the average like you did earlier
event_triggered_average = signal_chunks.mean(axis=0)

注意,带.astype(int)的行不舍入到最近的整数,而是舍入到零。在

相关问题 更多 >