我有一个大型3D numpy数组(1024 x 1024 x 1024),我需要找到局部最大值附近的区域,以便将所有大于例如局部最大值的50%的相邻点递归地聚集在同一地区。迭代算法为:
循环从最大值到最小值的局部最大值。
如果局部最大值已经分配给一个区域,则continue
遍历下一个局部最大值。
如果未将本地最大值分配给任何区域,则将其分配给新区域。令该局部最大值为M。
将局部最大值大于0.5 * M的所有邻居添加到该区域。
将所有邻居,邻居的邻居递归添加到区域中,其值> 0.5 * M。
重复直到将所有局部最大值分配给某个区域。
对于如此庞大的数组,该算法令人望而却步,因此我一直在寻找Python库的矢量化解决方案。
更具体地说,对于2D阵列,例如
0.0 1.6 0.0 0.0 0.0
0.0 2.0 1.0 0.0 5.0
1.6 3.0 1.0 0.0 4.6
0.0 0.0 0.0 9.0 4.6
会有两个这样的区域:
5.0
4.6
9.0 4.6
和
1.6
2.0
1.6 3.0
凭直觉,我正在寻找局部最大值附近的“山脉”,其中“山脉”由轮廓线定义,该轮廓线不是绝对的,而是相对于局部最大值的。
我尝试使用scipy.ndimage
,这对于首先找到局部最大值非常有用。但是我不知道如何获得周围的区域。我还研究了标准的聚类算法和图像处理技术,例如斑点检测或局部阈值处理,但似乎没有一个可以重现此问题。
任何建议表示赞赏。
提前致谢,
编辑:感谢taw,以下是一种解决方案
import math
import numpy as np
def soln(data, maxind):
test = np.pad(data,(1,1),'constant',constant_values = [-math.inf,-math.inf])
regionlist = {} # Dictionary with the results
for region, ind in enumerate(maxind): # Loop over all maxima
M = test[ind[0]+1, ind[1]+1, ind[2]+1] # Value of the maximum
if M == -np.inf:
continue
regionlist[region] = set()
regionlist[region].add(ind)
test[ind[0]+1, ind[1]+1, ind[2]+1] = -math.inf # All points that are added to the results are set to -infinity
neighbors = set()
neighbors.add((ind[0]+1, ind[1]+1, ind[2]+1))
while len(neighbors)>0: #create region iteratively
newneighbors = set() # This will contain the new elements in the region
for i in neighbors:
values = test[i[0]-1:i[0]+2, i[1]-1:i[1]+2, i[2]-1:i[2]+2] # Values of neighbours
valuesmask = values > .5*M # Neighbours that fall in region
list1 = range(i[0]-2, i[0]+1)
list2 = range(i[1]-2, i[1]+1)
list3 = range(i[2]-2, i[2]+1)
indlist = list(itertools.product(list1, list2, list3)) # 3-D list with coordinates of neighbours
for count,j in enumerate(valuesmask):
if j:
newneighbors.add(indlist[count])
#update iteration
newneighbors = newneighbors.difference(neighbors) # Remove all elements that were already iterated over and added to regionlist
regionlist[region].update(newneighbors) # Add the new elements in the region to regionlist
neighbors = set((x[0]-1, x[1]-1, x[2]-1) for x in newneighbors) # In the next iteration, iterate only over new elements in the region
for i in newneighbors:
test[i[0]+1, i[1]+1, i[2]+1] = -math.inf #set values to -inf after added to region
return regionlist
python大神给出的解决方案
我不确定如何定义“局部最大值”,或者您正在使用scipy.ndimage中的哪些函数来获取它们。这是一个函数,它将给出属于每个区域的索引集(返回索引,而不是值)。成本看起来像O(将分配给区域的点数)。该常数取决于数组的维数。我认为不可能做得比这更好(就复杂性而言)。
该解决方案也适用于二维阵列。
import math
import numpy as np
test = np.array([[0, 1.6, 0, 0, 0,], [0, 2, 1,0,5],[1.6,3,1,0,4.6],[0,0,0,9,4.6]])
maxind = [(3,3),(2,1)] #indices of maxima
def soln(data, maxind):
test = np.pad(data,(1,1),'constant',constant_values = [-math.inf,-math.inf])
regionlist = {}
for region,ind in enumerate(maxind): #all maxima
regionlist[region] = set()
regionlist[region].add(ind)
M = test[ind[0]+1,ind[1]+1]
test[ind[0]+1,ind[1]+1] = -math.inf
neighbors = set()
neighbors.add((ind[0]+1,ind[1]+1))
while len(neighbors)>0: #create region iteratively
newneighbors = set()
for i in neighbors:
values = test[i[0]-1:i[0]+2,i[1]-1:i[1]+2]
valuesmask = values.flatten() > .5*M
list1 = np.repeat(list(range(i[0]-2,i[0]+1)),3)
list2 = np.tile(list(range(i[1]-2,i[1]+1)), 3)
indlist = list(zip(list1,list2))
for count,j in enumerate(valuesmask):
if j:
newneighbors.add(indlist[count])
#update iteration
newneighbors = newneighbors.difference(neighbors)
regionlist[region].update(newneighbors)
neighbors = newneighbors
for i in newneighbors:
test[i[0]+1,i[1]+1] = -math.inf #set values to -inf after added to region
return regionlist
regionlist = soln(test, maxind)
Python sqlite3数据库已锁定 - python我在Windows上使用Python 3和sqlite3。我正在开发一个使用数据库存储联系人的小型应用程序。我注意到,如果应用程序被强制关闭(通过错误或通过任务管理器结束),则会收到sqlite3错误(sqlite3.OperationalError:数据库已锁定)。我想这是因为在应用程序关闭之前,我没有正确关闭数据库连接。我已经试过了: connectio…
Python pytz时区函数返回的时区为9分钟 - python由于某些原因,我无法从以下代码中找出原因:>>> from pytz import timezone >>> timezone('America/Chicago') 我得到:<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD…
用大写字母拆分字符串,但忽略AAA Python Regex - python我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…
如何打印浮点数的全精度[Python] - python我编写了以下函数,其中传递了x,y的值:def check(x, y): print(type(x)) print(type(y)) print(x) print(y) if x == y: print "Yes" 现在当我打电话check(1.00000000000000001, 1.0000000000000002)它正在打印:<…
Python:检查新文件是否在文件夹中[重复] - pythonThis question already has answers here: How do I watch a file for changes? (23个答案) 3年前关闭。 我是python的新手,但是我尝试创建一个自动化过程,其中我的代码将侦听目录中的新文件条目。例如,某人可以手动将zip文件复制到一个特定的文件夹中,并且我希望我的代码能够在文件完全…