python中定义数组的最大范围_Python,找到数组的所有局部最大值,调整测量中的缺陷...

i'm trying to get the maximum points in a one dimensional array, where it makes several curves. To do this i use scipy.signal.argrelextrema, along with np.greater. Give here where the array is y:

argrelextrema(y, np.greater)

The issue is, that this one dimensional data has inaccuracies due to the way the data for y was gathered. And so, there's a lot of "false positives" at the bottom of the curve, where there technically is a maxima at the bottom because of one value being bigger than the surrounding ones.

For reference, here's y, over x which is just the index of each y value, to demonstrate the array i'm working with. The inaccuracies at the bottom is not visible. Ignore axises, used what i had in the code.

Also, here's the result of me using the found maxima to calculate a value, as seen this is not wanted, as the expected result should have been a smooth falling curve. The graph was made with one point for each maxima, in an increasing order. And it's clearly wrong, as one can observe from the actual graph.

So, what's the best solution to avoid shis? I failed to find something that could approximate the graph in a good enough manner for me the be able to use it. I looked into smoothening, but the methods i found, like savgol_filter from scipy.signal, was something i could not understand.

The current solution was to ignore values of y that were below 5, which was roughly a bit over the bottom of the curve, but not an ideal solution at all.

Update:

Found out find_peaks_cwt from scipy.signal works for this too. It's a tad more complex as i have absolutely no clue how most of it works, even after reading up on it a bit. However, i managed to make a slightly better graph, i think, using: find_peaks_cwt(y, [3], noise_perc=2) However, the result seen below, is only a result of me dropping noise from 10 to 2, without really knowing how that affects the result.

Edit:

Here's is the 1D-array i'm working on: https://pastebin.com/GZrBBRce

Sorry for bad representation, but each line is the next value in the list. It's a bit large.

Edit: Minimum working examplem, y is from the pastebin, a bit large to include in minimum working example:

energy = []

for i in find_peaks_cwt(y, [3],noise_perc=2):

energy.append(y[i])

plt.plot([i for i in range(len(energy))], energy)

plt.show()

This was made with some guessing, and the result is seen in the last image in this question.

Update 2: Further progress, i smoothed out the y function using numpy.polyfit with a 15 degree approximation. It's surprisingly accurate. And since that is smooth, i can revert to the first function argrelextrema(y, np.greater), and it's gives me a pretty decent answer as well as not including false positives, as seen in the above graphs. (I got 30-40 maximas, when my graph only has a little above 20 of them.)

I'll let it stand a bit, before marking solved, in case anyone want to have a go at a better solution and approximating the graph with numpy.polyfit. However this solved the issue for my usecase.

解决方案

I would use: scipy.signal.find_peaks_cwt().

From its documentation:

Attempt to find the peaks in a 1-D array.

The general approach is to smooth vector by convolving it with wavelet(width) for each width in widths. Relative maxima which appear at enough length scales, and with sufficiently high SNR, are accepted.

UPDATE (with actual data)

import numpy as np

import scipy as sp

import matplotlib.pyplot as plt

import scipy.signal

y_arr = np.loadtxt('/home/raid1/metere/Downloads/1d_array.txt')

print('array size: ', y_arr.shape)

arr_size = len(y_arr)

expected_num = 30

expected_width = arr_size // expected_num // 2

print('expected width of peaks: ', expected_width)

peaks = sp.signal.find_peaks_cwt(y_arr, np.linspace(2, expected_width, 10))

print('num peaks: ', len(peaks))

print('peaks: ', peaks)

plt.plot(y_arr)

for peak in peaks:

plt.axvline(peak)

plt.show()

This can probably tweaked further, for example to increase the accuracy.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值