如何检查数组中至少五个元素的邻域是否满足条件?
How to check if a neighbourhood of at least five elements of an array satisfies a criterion?
我有一个 numpy 数组,我检查低于阈值(平均值 - 3 * 标准差)的局部最小值。在那些最小值中,我想要 select 那些在至少五个点附近的那些都低于阈值。如果某个邻域包含多个最小值,我想知道哪个最小值具有最低值。如何做到这一点并使其 运行 相对较快?
代码类似于 B.M 建议的代码。不能完全满足我的需要。
from numpy import *
a=random.rand(10)
n = ones(7)
threshold=0.5
u=convolve(a<t,n,'same')
这是它产生的结果:
X
阵列([0.6034448,0.16098872,0.39563129,0.33611677,0.90138981,
0.26088853、0.45720198、0.100786、0.47705187、0.15514734])
你
array([ 3., 3., 4., 5., 6., 6., 6., 5., 5., 4.])
这表明索引 6 处的元素是低于阈值 6 个点的邻域的一部分。我猜它还计算了索引为 3 的元素,这是不可取的行为,因为位置 4 的值 > 0.9。位置 9 的元素声称属于一组 4 个元素,而我会说它是一组5.
这是我目前对问题的解决方案:
layer = Xa
while layer > overlap:
if d[layer] > d[layer+1] and d[layer] > d[layer-1]:
if layer > 300:
threshold = threshold_free
else:
threshold = threshold_PBL
if d[layer] <= threshold:
upper_limit = layer
lower_limit = layer
k = 1
kp = 0
while kp < k and layer + kp < Xa:
kp = k
if d[layer+k] <= threshold:
upper_limit = layer + k
k += k
k = 1
kp = 0
while kp < k and layer - kp > overlap:
kp = k
if d[layer-k] <= threshold:
lower_limit = layer - k
k += k
transition_interval = upper_limit - lower_limit
if transition_interval >= 5:
print layer, upper_limit, lower_limit, upper_limit - lower_limit
layer = lower_limit
if valid_time in layers:
layers[valid_time].append(layer)
else:
layers[valid_time] = [layer]
layer -= 1
一些技巧可以做到这一点:
from numpy import *
from matplotlib.pyplot import *
from scipy.signal import convolve2d
from scipy.ndimage.filters import minimum_filter as mini
a=random.rand(100,100)
neighbours = ones((3,3))
threshold=0.2
u=convolve2d(a<threshold,neighbours,'same')
mins=((u>=6)*(a<threshold))
minis=mini(choose(mins,(1,a)),size=(3,3))==a
subplot(121);imshow(mins,cmap=cm.gray_r,interpolation='none')
subplot(122);imshow(minis,cmap=cm.gray_r,interpolation='none')
此脚本产生:
左图是有5个邻居的人,右图只选择了最小的。如果您想要索引和值,请使用 inds=mask_indices(100,lambda x,k: minis)
和 a[inds]
。
我有一个 numpy 数组,我检查低于阈值(平均值 - 3 * 标准差)的局部最小值。在那些最小值中,我想要 select 那些在至少五个点附近的那些都低于阈值。如果某个邻域包含多个最小值,我想知道哪个最小值具有最低值。如何做到这一点并使其 运行 相对较快?
代码类似于 B.M 建议的代码。不能完全满足我的需要。
from numpy import *
a=random.rand(10)
n = ones(7)
threshold=0.5
u=convolve(a<t,n,'same')
这是它产生的结果: X 阵列([0.6034448,0.16098872,0.39563129,0.33611677,0.90138981, 0.26088853、0.45720198、0.100786、0.47705187、0.15514734]) 你 array([ 3., 3., 4., 5., 6., 6., 6., 5., 5., 4.])
这表明索引 6 处的元素是低于阈值 6 个点的邻域的一部分。我猜它还计算了索引为 3 的元素,这是不可取的行为,因为位置 4 的值 > 0.9。位置 9 的元素声称属于一组 4 个元素,而我会说它是一组5.
这是我目前对问题的解决方案:
layer = Xa
while layer > overlap:
if d[layer] > d[layer+1] and d[layer] > d[layer-1]:
if layer > 300:
threshold = threshold_free
else:
threshold = threshold_PBL
if d[layer] <= threshold:
upper_limit = layer
lower_limit = layer
k = 1
kp = 0
while kp < k and layer + kp < Xa:
kp = k
if d[layer+k] <= threshold:
upper_limit = layer + k
k += k
k = 1
kp = 0
while kp < k and layer - kp > overlap:
kp = k
if d[layer-k] <= threshold:
lower_limit = layer - k
k += k
transition_interval = upper_limit - lower_limit
if transition_interval >= 5:
print layer, upper_limit, lower_limit, upper_limit - lower_limit
layer = lower_limit
if valid_time in layers:
layers[valid_time].append(layer)
else:
layers[valid_time] = [layer]
layer -= 1
一些技巧可以做到这一点:
from numpy import *
from matplotlib.pyplot import *
from scipy.signal import convolve2d
from scipy.ndimage.filters import minimum_filter as mini
a=random.rand(100,100)
neighbours = ones((3,3))
threshold=0.2
u=convolve2d(a<threshold,neighbours,'same')
mins=((u>=6)*(a<threshold))
minis=mini(choose(mins,(1,a)),size=(3,3))==a
subplot(121);imshow(mins,cmap=cm.gray_r,interpolation='none')
subplot(122);imshow(minis,cmap=cm.gray_r,interpolation='none')
此脚本产生:
左图是有5个邻居的人,右图只选择了最小的。如果您想要索引和值,请使用 inds=mask_indices(100,lambda x,k: minis)
和 a[inds]
。