Python下一步中的最小元素



此代码查找每行的最小值,并扫描相邻元素以查找下一个最小值。但我不希望它回到前一行。例如,对于第2行,最小值为0.021。我希望它扫描元素0.28(第2行(、0.78(第3行(、0.85(第3列(,而不是0.34(第1行(、0.002(第1列(。

import numpy as np
import seaborn as sns
import matplotlib.pylab as plt
#Pe = np.random.rand(3,3) 
Pe = np.array([[0.32, 0.34 , 0.002],
[0.74, 0.28, 0.021],
[0.69, 0.78, 0.85]])
b = np.zeros((Pe.shape[0], 2))
Pw=0.5
for row_n, row in enumerate(Pe):
# Get row min
b[row_n][0] = np.min(row)

# Get surroundings min
i = np.argmin(row)
near = []
if row_n > 0:
near.append(Pe[row_n-1][i])
if row_n+1 < b.shape[0]:
near.append(Pe[row_n+1][i])
if i > 0:
near.append(Pe[row_n][i-1])
if i+1 < b.shape[1]:
near.append(Pe[row_n][i+1])
b[row_n][1] = min(near)
print(b)

电流输出:

[[0.002 0.021]
[0.021 0.002]
[0.69 0.74]]

我想要的输出:

[[0.002 0.021]
[0.021 0.28]
[0.69 0.78]]

如果使用numpy数组,则应尽量避免使用for循环进行显式迭代。scipy的ndimage模块可以有效地处理问题中描述的任务,因为它提供了方便的滑动窗口功能。在这里,我们使用最小滤波器:

import numpy as np
from scipy.ndimage import minimum_filter as mf
#Pe = np.random.rand(3,3) 
Pe = np.array([[0.32, 0.34 , 0.002],
[0.74, 0.28, 0.021],
[0.69, 0.78, 0.85]])
b = np.zeros((Pe.shape[0], 2))
#the footprint of the window, i.e., we do not consider the value itself 
#(the center of the footprint array) or any value in the row above
ft = np.asarray([[0, 0, 0],
[1, 0, 1],
[1, 1, 1]])
#applying scipy's minimum filter
#mode defines what should be considered as values at the edges
#setting the edges to INF
Pe_min = mf(Pe, footprint=ft, mode="constant", cval=np.inf)
#finding rowwise index of the minimum value using np.argmin()
idx = Pe.argmin(axis=1)
#retrieving minimum values and filtered values
b[:, 0] = np.take_along_axis(Pe, idx[None].T, 1).T[0]
b[:, 1] = np.take_along_axis(Pe_min, idx[None].T, 1).T[0]
print(b)

样本输出:

[[0.002 0.021]
[0.021 0.28 ]
[0.69  0.78 ]]

应当注意,如果相同的最小值出现多次,则np.argmin每行返回第一个最小值。但是,你的问题没有考虑到这种情况。

最新更新