在 Numpy 中的局部最小值之前分割信号
split signal right before local minima in Numpy
考虑以下名为 final1
的 numpy 数组(信号):
我想把之前的数组分成4个子数组。四个子数组在局部最小值之前的时刻分开,如下图所示:
我的想法是找到数组的局部最小值和最大值索引和值:
minimaindex = argrelextrema(final1, np.less)
maximaindex = argrelextrema(final1, np.greater)
valuesminima = final1[argrelextrema(final1, np.greater)[0]]
valuesmaxima = final1[argrelextrema(final1, np.less)[0]]
然后根据值数组对索引数组进行排序,考虑 4 个最大的最小值,最后找到与四个最小值最接近的最大值,并根据这些值的索引拆分 final1
数组。
我想知道是否有人对如何完成最后一部分有建议。
谢谢
编辑:
这是信号向量:
https://app.box.com/s/isog7pa3xcradzcsivn5vtx7mj8u0wp1
您可以使用 argsort 获取较小最小值的索引:
valuesminima = final1[minimaindex]
# Find 4 smaller minimas
idx = np.argsort(valuesminima) # sort minima
target = idx[:4] # 4 smaller minimas
# Find all maximas
argmaximas = argrelextrema(final1, np.less)
# Extract maximas closest to the minimas
maximas = []
for minidx in minimaindex[target]: # for each minima
dist = np.abs(argmaximas - minidx) # distance current minima
maximas += [np.argmin(dist)] # get the closest maxima
不太花哨,但我想它可以工作。 maximas
包含最接近较小的 4 个最小值的 4 个最大值。
我不确定接受的答案通常会按照您在图表上显示的那样进行。我当然不能让它产生正确的答案!
通常,您总是会得到交替的最大值和最小值,其中 none 的边缘情况是一个或两个。您需要查看所有在它们之前有最大值的最小值,而无需搜索所有最大值以查看哪个最近。此外,您的图表上只有三个切点。
您有很多 "noise" 最大值和最小值,这很容易打乱您的结果 - 进行一些平滑处理是个好主意。此外,您使用 argrelextrema 的方式实际上与
相同
np.where((a[:-2] > a[1:-1]) & (a[1:-1] < a[2:]))
(这可能会更快,但您必须 +1 来索引值)两者都会错过一个恰好有两个值相同的转折点。
无论如何,这似乎对我有用你的数据:
import numpy as np
from scipy import signal
final1 = np.loadtxt("/home/jill/Downloads/256frames_timed_SumrowSignal_1.csv", delimiter=",")
#final1 = np.convolve(final1, [0.1, 0.2, 0.4, 0.2, 0.1])
minimaindex = signal.argrelextrema(final1, np.less)[0]
maximaindex = signal.argrelextrema(final1, np.greater)[0]
if minimaindex[0] < maximaindex[0]: # ensure all minima have a previous maxima
minimaindex = minimaindex[1:]
maximaindex = maximaindex[:len(minimaindex)]
diffs = final1[maximaindex] - final1[minimaindex]
diffs_as = np.argsort(diffs)[-3:]
cut_points = maximaindex[diffs_as]
编辑如果您查看所附图片,您会发现您总是必须交替使用最大值和最小值 - 因为它们是什么。
您必须注意的情况是第一个最小值的左侧没有最大值点。这就是我检查每个索引的第一个索引的行所做的。如果最大值不是第一个,它会砍掉第一个最小值。它还必须确保最大值列表被截断为与最小值相同的长度。
我不检查的情况就像下面两行。如果没有足够的最小值或最大值,您可以在这里停止该过程:
if minimaindex[0] < maximaindex[0]: # ensure all minima have a previous maxima
minimaindex = minimaindex[1:]
if len(minimaindex) < 3 or len(maximaindex) < 3:
error_message = "not enough peaks"
return None #break, exit, whatever is relevant to the way you use the code
maximaindex = maximaindex[:len(minimaindex)]
考虑以下名为 final1
的 numpy 数组(信号):
我想把之前的数组分成4个子数组。四个子数组在局部最小值之前的时刻分开,如下图所示:
我的想法是找到数组的局部最小值和最大值索引和值:
minimaindex = argrelextrema(final1, np.less)
maximaindex = argrelextrema(final1, np.greater)
valuesminima = final1[argrelextrema(final1, np.greater)[0]]
valuesmaxima = final1[argrelextrema(final1, np.less)[0]]
然后根据值数组对索引数组进行排序,考虑 4 个最大的最小值,最后找到与四个最小值最接近的最大值,并根据这些值的索引拆分 final1
数组。
我想知道是否有人对如何完成最后一部分有建议。
谢谢
编辑: 这是信号向量: https://app.box.com/s/isog7pa3xcradzcsivn5vtx7mj8u0wp1
您可以使用 argsort 获取较小最小值的索引:
valuesminima = final1[minimaindex]
# Find 4 smaller minimas
idx = np.argsort(valuesminima) # sort minima
target = idx[:4] # 4 smaller minimas
# Find all maximas
argmaximas = argrelextrema(final1, np.less)
# Extract maximas closest to the minimas
maximas = []
for minidx in minimaindex[target]: # for each minima
dist = np.abs(argmaximas - minidx) # distance current minima
maximas += [np.argmin(dist)] # get the closest maxima
不太花哨,但我想它可以工作。 maximas
包含最接近较小的 4 个最小值的 4 个最大值。
我不确定接受的答案通常会按照您在图表上显示的那样进行。我当然不能让它产生正确的答案!
通常,您总是会得到交替的最大值和最小值,其中 none 的边缘情况是一个或两个。您需要查看所有在它们之前有最大值的最小值,而无需搜索所有最大值以查看哪个最近。此外,您的图表上只有三个切点。
您有很多 "noise" 最大值和最小值,这很容易打乱您的结果 - 进行一些平滑处理是个好主意。此外,您使用 argrelextrema 的方式实际上与
相同np.where((a[:-2] > a[1:-1]) & (a[1:-1] < a[2:]))
(这可能会更快,但您必须 +1 来索引值)两者都会错过一个恰好有两个值相同的转折点。
无论如何,这似乎对我有用你的数据:
import numpy as np
from scipy import signal
final1 = np.loadtxt("/home/jill/Downloads/256frames_timed_SumrowSignal_1.csv", delimiter=",")
#final1 = np.convolve(final1, [0.1, 0.2, 0.4, 0.2, 0.1])
minimaindex = signal.argrelextrema(final1, np.less)[0]
maximaindex = signal.argrelextrema(final1, np.greater)[0]
if minimaindex[0] < maximaindex[0]: # ensure all minima have a previous maxima
minimaindex = minimaindex[1:]
maximaindex = maximaindex[:len(minimaindex)]
diffs = final1[maximaindex] - final1[minimaindex]
diffs_as = np.argsort(diffs)[-3:]
cut_points = maximaindex[diffs_as]
编辑如果您查看所附图片,您会发现您总是必须交替使用最大值和最小值 - 因为它们是什么。
您必须注意的情况是第一个最小值的左侧没有最大值点。这就是我检查每个索引的第一个索引的行所做的。如果最大值不是第一个,它会砍掉第一个最小值。它还必须确保最大值列表被截断为与最小值相同的长度。
我不检查的情况就像下面两行。如果没有足够的最小值或最大值,您可以在这里停止该过程:
if minimaindex[0] < maximaindex[0]: # ensure all minima have a previous maxima
minimaindex = minimaindex[1:]
if len(minimaindex) < 3 or len(maximaindex) < 3:
error_message = "not enough peaks"
return None #break, exit, whatever is relevant to the way you use the code
maximaindex = maximaindex[:len(minimaindex)]