numpy 如何在数组中找到最小值

qni6mghb  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(108)

我有一个代码来绘制一组数据的热图,表示为(x, y, f(x, y)),我想找到局部最小点。

import numpy as np
import math
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy.interpolate import griddata

data = np.genfromtxt('data.dat',
                     skip_header=1,
                     delimiter='        ')

x, y, z = data[:, 1], data[::, 0], data[:, 2]
x, y, z = x*180/math.pi, y*180/math.pi, z - min(z)

xi, yi = np.linspace(max(x), min(x), 1000), np.linspace(max(y), min(y), 1000)

xi, yi = np.meshgrid(xi, yi)

zi = griddata((x, y), z, (xi, yi), method='linear')

plt.figure(figsize=(10,5))
plt.pcolormesh(xi, yi, zi, shading='auto', cmap='jet')

plt.colorbar(label='Heatmap')

plt.gca().invert_yaxis()

plt.show()

下面是生成一些假数据的代码:

import math

with open('data.dat', 'w') as arquivo:

    for x in range(20):
        for y in range(20):
            z = -math.exp(math.sin(x*y)- math.cos(y))
            arquivo.write(f"{x}\t\t{y}\t\t{z}\n")

圈出最小点的热图示例:

我试着使用np.gradient,以为通过求两个导数,我就可以确定局部极小点(一阶导数为零,二阶导数为负),但我无法使任何一个函数起作用。

unguejic

unguejic1#

为了找到局部最小值,我们通常使用一些基于梯度的优化,如梯度下降。然而,要找到所有的局部极小值并不容易,除非做很多“重启”(通常人们对一个局部极小值很满意)。解决问题的一个简单方法是使用网格搜索:如果当前点小于它周围的相邻点,则它是一个局部最小值。代码片段如下所示

# Function to get the neighbors of a given point (i,j)
def get_neighbors(i, j, shape):
    neighbors = []

    for x in [-1, 0, 1]:
        for y in [-1, 0, 1]:
            ni, nj = i + x, j + y

            if (0 <= ni < shape[0]) and (0 <= nj < shape[1]) and (x, y) != (0, 0):
                neighbors.append((ni, nj))

    return neighbors

local_minima = []

# Iterate over the 2D grid
for i in range(zi.shape[0]):
    for j in range(zi.shape[1]):
        current_value = zi[i, j]
        neighbors = get_neighbors(i, j, zi.shape)

        # Check if the current point is less than all its neighbors
        if all(current_value < zi[n[0], n[1]] for n in neighbors):
            local_minima.append((xi[i, j], yi[i, j], current_value))
# Print the local minima
for loc in local_minima:
    print(f"Local minimum value {loc[2]} at location ({loc[0]}, {loc[1]}).")

然后画出局部最小值

# Marking all the local minima on the plot
for loc in local_minima:
    plt.scatter(loc[0], loc[1], color='red', s=100, marker='x')

hof1towb

hof1towb2#

有几种方法可以做到这一点,但我的方法是使用scipy过滤器(如均匀过滤器)创建Map背景的模型,其大小足以包含Map上的几个主要特征(例如图像大小的一半)。然后使用标准差过滤器创建贴图标准差的另一个模型。
局部极小值出现在(original_map - background) / standard_deviation < threshold_value处。
你可以随意使用threshold_value(也许负2-3就可以)和过滤窗口的大小。
python代码作为练习。:)

相关问题