在scipy中简单计算:最小值

1 投票
2 回答
708 浏览
提问于 2025-04-18 05:34
import numpy as np
from scipy import signal

data = np.array([[[*3, 2, 1, np.nan, np.nan],
              [22, 1, 1, 4, 4],
              [4, 2, 3, 3, 4],
              [1, 1, 4, 1, 5],
              [2, 4, 5, 2, 1]],

             [[*6, 7, 10, 6, np.nan],
              [np.nan, 7, 8, 6, 9],
              [6, 10, 9, 8, 10],
              [6, 8, 7, 10, 8],
              [10, 9, 9, 10, 8]],

             [[*6, 7, 10, np.nan, np.nan],
              [19, 19, 8, 6, 9],
              [6, 10, 9, 8, 10],
              [6, 8, 7, 10, 8],
              [10, 9, 9, 10, 8]],

             [[*6, 7, 10, 6, np.nan],
              [19, 21, 8, 6, 9],
              [6, 10, 9, 8, 10],
              [6, 8, 7, 10, 8],
              [10, 9, 9, 10, 8]],

             [[*12, 14, 12, 15, np.nan],
              [19, 11, 14, 14, 11],
              [13, 13, 16, 15, 11],
              [14, 15, 14, 16, 14],
              [13, 15, 11, 11, 14]]])

我想计算最小值。 从五个用星号表示的元素中找出一个最小值,依此类推。因此,最终会得到25个最小值,这些值会形成一个5*5的数组。 我尝试了以下方法:

data = data.reshape(5,25)
minima = data[signal.argrelmin(data,axis=0,order=1)]
print minima

但是,出现了以下错误。请问有什么想法吗?

IndexError: arrays used as indices must be of integer (or boolean) type

2 个回答

1

你有没有检查过signal.argrelmin()对你的(重新调整形状的)数据实际返回了什么?你需要正确选择轴。举个简单的例子,

data = np.array([[19, 11, 14, 14, 10],[19,21,12,14,11]])
scipy.signal.argrelmin(data)

会返回

(array([], dtype=float64), array([], dtype=float64))

这就会导致你提到的IndexError错误。

1

注意:我的Python现在有点问题,所以我还没能测试这个。如果我说错了,请告诉我。

你的数据在重新调整形状为(5,25)后,沿着第一个轴(也就是行)是全部递增的。这意味着在使用argrelmin(data, axis=0)时,没有相对最小值,除非你指定mode='wrap'。如果这样做,每个向量的第一个元素会被视为最小值。不过,当向量里的所有元素都是NaN(在你的数据集中确实有这种情况)或者最后一个元素是NaN时,这个说法就不一定成立了。因为argrelmin使用np.less进行比较(对于NaN的比较结果总是返回False),所以我猜无论你怎么修改函数调用,你都不会在那些行中找到最小值(虽然我还没尝试过)。

总结一下:argrelmin返回空数组的原因是因为你的数据集在第一个轴上没有相对最小值。另外,除非你能做一些特定的假设(比如数据是递增的、使用wrap模式,并且没有NaN),否则你不能保证你的数据集中有25个最小值。

这也是为什么在沿着第二个轴(axis 1)使用argrelmin时,你会得到27个元素的原因——因为有27个相对最小值。

例如:

正常情况下:

3., 2., 1., nan, nan, 22., 1., 1., 4., 4., 4., 2., 3., 3., 4., 1., 1., 4., 1., 5., 2., 4., 5., 2., 1.

使用wrap模式:

3., 2., 1., nan, nan, 22., 1., 1., 4., 4., 4., 2., 3., 3., 4., 1., 1., 4., 1., 5., 2., 4., 5., 2., 1.

注意:看起来你可以自己创建一个比较器来处理NaN,并把它传给argrelextrema,但你仍然需要处理所有NaN的情况等等。

撰写回答