Python:二维 numpy 数组中峰的正确位置?
Python: correct location of peaks in a 2D numpy array?
我知道这个问题属于峰值检测的范畴,there are answers available,但我认为我的问题非常简单,涉及原理证明。
假设我生成多个 nxn
浮点值的 2D numpy 数组,它指的是 nxn
点(离散域)的规则网格:
myarray=
array([[ 0.82760819, 0.82113999, 0.811576 , 0.80308705, 0.81231903,
0.82296263, 0.78448964, 0.79308308, 0.82160627, 0.83475755,
0.8580934 , 0.8857617 , 0.89901092, 0.92479025, 0.91840606,
0.91029942, 0.88523943, 0.85798491, 0.84190422, 0.83350783,
0.83520675],
[ 0.84971526, 0.84759644, 0.81429419, 0.79936736, 0.81750327,
0.81874686, 0.80666801, 0.82297348, 0.84980788, 0.85698662,
0.87819988, 0.89572185, 0.89009723, 0.90347858, 0.89703473,
0.90092666, 0.88362073, 0.86711197, 0.84791422, 0.83632138,
0.83685225], ...] #you can generate any nxn array of random values
现在让我们标准化它们:
peak_value=myarray.max()
norm_array=myarray/peak_value
然后继续定位峰的(x,y)
坐标:
from collections import Counter
longit=[] #x values of the peak
latit=[] #y values of the peak
for x in range(myarray.shape[0]):
for y in range(myarray.shape[1]):
if norm_array[x][y]==1:
longit.append(x)
latit.append(y)
x=numpy.array(longit)
y=numpy.array(latit)
c=zip(x,y)
temp=Counter(elem for elem in c) #Counts the number of peaks in each (x,y) point in the 11x11 grid
d=dict(Counter(temp)) #Has the shape d={(x,y): number of peaks}
现在这只是二维 numpy 数组的一个实现。给定多个数组,问题是:
这是找到峰的 (x,y) 的正确方法吗?有没有更有效的方法?考虑到可能有多个峰。
在 C/C++ 中,使用浮点数 ==
被认为是危险的。
如果没有多个完全相同的派克,可以使用numpy.argmax
:
a = random.rand(13, 11)
idx_unrolled = argmax(a)
the_peak = a[idx_unrolled/11, idx_unrolled%11]
如果您需要所有长矛,您可以使用 numpy.where
:
获取 i
、j
索引的列表
i, j = where(a > 0.99*the_peak)
使用所需数量的 9
来调整边距。对于单精度浮点数,它不接近 1
。
最好的方法可能是 [ ]:
i, j = where(a > (1.0 - 5*np.finfo(a.dtype).eps)*the_peak)
我知道这个问题属于峰值检测的范畴,there are answers available,但我认为我的问题非常简单,涉及原理证明。
假设我生成多个 nxn
浮点值的 2D numpy 数组,它指的是 nxn
点(离散域)的规则网格:
myarray=
array([[ 0.82760819, 0.82113999, 0.811576 , 0.80308705, 0.81231903,
0.82296263, 0.78448964, 0.79308308, 0.82160627, 0.83475755,
0.8580934 , 0.8857617 , 0.89901092, 0.92479025, 0.91840606,
0.91029942, 0.88523943, 0.85798491, 0.84190422, 0.83350783,
0.83520675],
[ 0.84971526, 0.84759644, 0.81429419, 0.79936736, 0.81750327,
0.81874686, 0.80666801, 0.82297348, 0.84980788, 0.85698662,
0.87819988, 0.89572185, 0.89009723, 0.90347858, 0.89703473,
0.90092666, 0.88362073, 0.86711197, 0.84791422, 0.83632138,
0.83685225], ...] #you can generate any nxn array of random values
现在让我们标准化它们:
peak_value=myarray.max()
norm_array=myarray/peak_value
然后继续定位峰的(x,y)
坐标:
from collections import Counter
longit=[] #x values of the peak
latit=[] #y values of the peak
for x in range(myarray.shape[0]):
for y in range(myarray.shape[1]):
if norm_array[x][y]==1:
longit.append(x)
latit.append(y)
x=numpy.array(longit)
y=numpy.array(latit)
c=zip(x,y)
temp=Counter(elem for elem in c) #Counts the number of peaks in each (x,y) point in the 11x11 grid
d=dict(Counter(temp)) #Has the shape d={(x,y): number of peaks}
现在这只是二维 numpy 数组的一个实现。给定多个数组,问题是:
这是找到峰的 (x,y) 的正确方法吗?有没有更有效的方法?考虑到可能有多个峰。
在 C/C++ 中,使用浮点数 ==
被认为是危险的。
如果没有多个完全相同的派克,可以使用numpy.argmax
:
a = random.rand(13, 11)
idx_unrolled = argmax(a)
the_peak = a[idx_unrolled/11, idx_unrolled%11]
如果您需要所有长矛,您可以使用 numpy.where
:
i
、j
索引的列表
i, j = where(a > 0.99*the_peak)
使用所需数量的 9
来调整边距。对于单精度浮点数,它不接近 1
。
最好的方法可能是 [ ]:
i, j = where(a > (1.0 - 5*np.finfo(a.dtype).eps)*the_peak)