强制数组中非零元素之间的最小间距
Enforce minimum spacing between non-zero elements in array
我正在尝试生成零和一的数组,其中零和一之间的间距是泊松分布的。
我相信这段代码可以解决问题:
import numpy as np
dt = 0.05
n_t = 500 / dt # desired length of array
r = 100
spike_train = (np.random.rand(n_t) < r * dt).astype(int)
但是,我还想在 1 之间强制执行最小间距 - 例如任意两个 1 之间至少有两个零。
执行此操作的有效方法是什么?
我想在这个(不太优雅的)逻辑中保持分布:
def assure_2zeros(l):
for idx in range(len(l)):
# detect the problem when the ones are adjacent
if l[idx] == 1 and l[idx+1] == 1:
# check forward for a zero that could be realocated to split the ones
for i in range(idx+2, len(l)-1):
# check to not create other problems
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
# if doesnt found any zero forward, check backward
else:
for i in range(idx-1, 0, -1):
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
# detects the problem when there are one zero between the ones
if l[idx] == 1 and l[idx+2] == 1:
for i in range(idx+3, len(l)-1):
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
else:
for i in range(idx-1, 0, -1):
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
return l
注意当有两个相邻的时,第一个if会在它们之间插入一个零,然后在第二个if中输入,并插入第二个零。但是,当列表的末尾或开头有两个或一个零时,它会失败。可以在 if 语句中添加更多条件,但对于您的情况,有很多零,我认为它可以工作。
这是一个相当有效的方法。它的工作原理是 (1) 首先忽略最短等待时间。 (2) 计算事件间时间 (3) 添加最小等待时间,(4) 返回到绝对时间,丢弃已从右端移出的事件。它可以在不到一秒的时间内创建 10**7 个样本。
import numpy as np
def train(T, dt, rate, min_wait):
p = dt*rate
# correct for minimum wait
if p:
p = 1 / (1 / p - min_wait)
if p > 0.1:
print("warning: probability too high for approximation to be good")
n = int(np.ceil(T/dt))
raw_times, = np.where(np.random.random(n) < p)
raw_times[1:] += min_wait - raw_times[:-1]
good_times = raw_times.cumsum()
cut = good_times.searchsorted(n)
result = np.zeros(n, int)
result[good_times[:cut]] = 1
return result
我正在尝试生成零和一的数组,其中零和一之间的间距是泊松分布的。
我相信这段代码可以解决问题:
import numpy as np
dt = 0.05
n_t = 500 / dt # desired length of array
r = 100
spike_train = (np.random.rand(n_t) < r * dt).astype(int)
但是,我还想在 1 之间强制执行最小间距 - 例如任意两个 1 之间至少有两个零。
执行此操作的有效方法是什么?
我想在这个(不太优雅的)逻辑中保持分布:
def assure_2zeros(l):
for idx in range(len(l)):
# detect the problem when the ones are adjacent
if l[idx] == 1 and l[idx+1] == 1:
# check forward for a zero that could be realocated to split the ones
for i in range(idx+2, len(l)-1):
# check to not create other problems
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
# if doesnt found any zero forward, check backward
else:
for i in range(idx-1, 0, -1):
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
# detects the problem when there are one zero between the ones
if l[idx] == 1 and l[idx+2] == 1:
for i in range(idx+3, len(l)-1):
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
else:
for i in range(idx-1, 0, -1):
if l[i] == 0 and l[i-1]== 0 and l[i+1]== 0:
del l[i]
l.insert(idx+1, 0)
break
return l
注意当有两个相邻的时,第一个if会在它们之间插入一个零,然后在第二个if中输入,并插入第二个零。但是,当列表的末尾或开头有两个或一个零时,它会失败。可以在 if 语句中添加更多条件,但对于您的情况,有很多零,我认为它可以工作。
这是一个相当有效的方法。它的工作原理是 (1) 首先忽略最短等待时间。 (2) 计算事件间时间 (3) 添加最小等待时间,(4) 返回到绝对时间,丢弃已从右端移出的事件。它可以在不到一秒的时间内创建 10**7 个样本。
import numpy as np
def train(T, dt, rate, min_wait):
p = dt*rate
# correct for minimum wait
if p:
p = 1 / (1 / p - min_wait)
if p > 0.1:
print("warning: probability too high for approximation to be good")
n = int(np.ceil(T/dt))
raw_times, = np.where(np.random.random(n) < p)
raw_times[1:] += min_wait - raw_times[:-1]
good_times = raw_times.cumsum()
cut = good_times.searchsorted(n)
result = np.zeros(n, int)
result[good_times[:cut]] = 1
return result