0910---scipy.signal.argrelextrema 计算多维数组局部极值问题

scipy signal argrelextrema 计算多维数组局部极值问题

在科学计算中,求一组数据的极值非常普遍,利用python scipy 工具包可以非常高效的计算局部极值,但在处理多维数组数据时,因选取的axis轴向不同,结果具有不同的意义,在理解上也比较困难。本文结合实例,进行透彻分析。

运行环境: Anaconda3

一 1维数组

1 引入工具包

import numpy as np
from scipy.signal import argrelextrema

2 案例

# 例子1
x = np.array([2, 1, 2, 3, 2, 0, 1, 0])
trema = argrelextrema(x, np.greater)
trema

# 输出结果
out (array([3, 6], dtype=int64),)
print('return type:',type(e_1D))
print('tuple lenth:',len(e_1D))
print('tuple element type:',type(e_1D[0]))

return type: <class 'tuple'>
tuple lenth: 1
tuple element type: <class 'numpy.ndarray'>
first data of first tuple element: 3

解释:由于上述例子是求一维数组的局部极大值,结果是返回一个元组,返回元组的元素类型是numpy.ndarray,里面存储局部极值的位置标记,即索引编号为3和6的位置标记信息。因一维数组只有一个X轴(0轴,如果给定 axis=1,会产生错误。

在这里插入图片描述

二 2维数组

对于2维数组求极值问题,官方文档给出了一个非常容易引起歧义的例子,下面就该例子进行分析。

# 例子2
y = np.array([ [1, 2, 1, 2],
               [2, 2, 0, 0],
               [5, 3, 4, 4]])
argrelextrema(y, np.less, axis=1)

# out 输出
(array([0, 2], dtype=int64), array([2, 1], dtype=int64))

说明:当 axis=1时,按y轴的方向进行局部极值判断,即以行为单元进行数据比较。

在这里插入图片描述

在这里插入图片描述

由此可见,二维数组的局部极小值有2个,一个是位于第0行第2列的1,另一个是第2行第一列的3,以蓝色圆圈标出,与输出结果 (array([0, 2], dtype=int64), array([2, 1], dtype=int64)) 相符。

当 axis =0 时,按x轴的方向进行局部极小值判断,即以列为单元进行数值比较。

# 例子3
argrelextrema(y, np.less, axis=0)
# out 输出 
(array([1, 1], dtype=int64), array([2, 3], dtype=int64))

在这里插入图片描述

结果应该是元素(1,2)和元素(1,3), 但输出的结果是 (array([1, 1], dtype=int64), array([2, 3], dtype=int64)),怎么都对应不上。

查找官方文档,signal.argrelextrema 的返回值有如下解释

返回值extrema : tuple of ndarrays
Indices of the maxima in arrays of integers. extrema[k] is
the array of indices of axis k of data. Note that the
return value is a tuple even when data is 1-D.

返回值extrema:由 ndarrays数组作为元素组成的元组,极值的位置由ndarrays数组中的整数值给出。extrema[k] 代表数据在k轴上的位置标记数组。注意,在数据是1维数组的情况下,返回结果仍然是元组。

对于例子3,返回结果 (array([1, 1], dtype=int64), array([2, 3], dtype=int64))是含有2个元素的元组,

extrema[0]代表的是 x 轴极值位置标记(行标记),extrema[1]代表的是y轴极值位置标记(列标记)。转换维人们习惯的行列坐标形式应该是:(extrema[0] [0], extrema[1] [0]) , (extrema[0] [1], extrema[1] [1]) , 即 (1,2) , (1,3).

回过头来解释例子2,返回结果是 (array([0, 2], dtype=int64), array([2, 1], dtype=int64)),对应的行列坐标是(0,2),(2,1),正好和返回的元组元素一样,这就是官方例子的不恰当之处。

在这里插入图片描述

三 2维数组的扩展案例

1 数据及运行结果(axis=1)

y1 = np.array([
    [ 1 , 2 , 1 , 2 , 1 ],
    [ 2 , 2 , 0 , 5 , 0 ],
    [ 5 , 3 , 4 , 4 , 2 ],
    [ 1 , 2 , 1 , 2 , 3 ],
    [ 4 , 3 , 0 , 3 , 2 ],
    [ 6 , 2 , 7 , 1 , 0 ]
    ])
    
extrema =  argrelextrema(y1, np.less, axis=1)

(array([0, 1, 2, 3, 4, 5], dtype=int64),
 array([2, 2, 1, 2, 2, 1], dtype=int64))
 对应的行列坐标是:(0,2),(1,2),(2,1),(3,2),(4,2),(5,1)

2 图示(axis=1)

在这里插入图片描述

3 数据及运行结果(axis=0)

y1 = np.array([
    [ 1 , 2 , 1 , 2 , 1 ],
    [ 2 , 2 , 0 , 5 , 0 ],
    [ 5 , 3 , 4 , 4 , 2 ],
    [ 1 , 2 , 1 , 2 , 3 ],
    [ 4 , 3 , 0 , 3 , 2 ],
    [ 6 , 2 , 7 , 1 , 0 ]
    ])
    
extrema = argrelextrema(y1, np.less, axis=0)

(array([1, 1, 3, 3, 3, 4], dtype=int64),
 array([2, 4, 0, 1, 3, 2], dtype=int64))
 
 对应的行列坐标是:(1,2),(1,4),(3,0),(3,1),(3,3),(4,2)

4 图示(axis=0)

在这里插入图片描述

                              2022-09-12
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值