Python 中下一步的最小元素
Minimum element in next step in Python
此代码查找每行的最小值并扫描相邻元素以查找下一个最小值。但我不希望它 return 到上一行。例如,对于第 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's ndimage module can efficiently address tasks like that described in your question as it provides convenient sliding windows functions. Here, we use the minimum filter:
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
returns 如果同一个最小值多次出现,则每行第一个最小值。但是,你的问题没有考虑到这种情况。
此代码查找每行的最小值并扫描相邻元素以查找下一个最小值。但我不希望它 return 到上一行。例如,对于第 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's ndimage module can efficiently address tasks like that described in your question as it provides convenient sliding windows functions. Here, we use the minimum filter:
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
returns 如果同一个最小值多次出现,则每行第一个最小值。但是,你的问题没有考虑到这种情况。