python - python - 如何更新数组中的每个元素以增加数据的平均值
问题描述
我有在 -4 和 4 之间标准化的音频数据;但是,我需要将波形/数据的“中心”(意思是?)以“1”为中心(请参见附图)
如何操作平均值被转换/转换为〜1的数据列表?同时仍保持 -4 到 4 的正常化
有没有一种简单的方法可以使用 numpy 做到这一点?
解决方案
将来,如果您提供一个可以修补的示例,那就太好了。第二个问题是你没有告诉我们使用什么类型的函数或者它应该保留什么属性。由于显然没有线性函数可以满足您的要求,因此我将使用二次函数。但首先这是我要修补的“声音”
np.random.seed(1)
x = np.linspace(0,0.01,10**4)
y = 0.1*np.sin(50*2*np.pi*x/(0.01))+np.random.random()*np.sin(50*2*np.pi*x/(0.01))*((0.0067<x)&(x<0.007))+((0.0067<x)&(x<0.007))*0.2
y -= y.mean()
plt.plot(x,y)
它不是你原来的那个,但它具有在居中后不在 -1 和 1 之间的属性。由于它看起来更干净,我将居中到零并且范围为 -1 和 1,但这应该没有真正的区别。我的计划是选择将最大值映射到 1、最小值映射到 -1 的唯一二次函数,然后选择一个好的值将 0 发送到平均值为零的值。
import sympy
a,b,c = sympy.symbols('a, b, c')
def change_scale(arr, lamb=0):
m = arr.min()
M = arr.max()
eqns = [a*x**2+b*x+c-y for x,y in zip([m,0,M],[-1,lamb,1])]
sols = sympy.solve(eqns,[a,b,c])
d,e,f = map(np.float64, sols.values())
return d*arr**2+e*arr+f
y2 = change_scale(y)
print(y2.mean())
plt.plot(x,y2)
对我来说,这几乎看起来不错。唯一的问题是,现在的平均值是-0.015
。好吧,但为此我们有那个 lambda 参数。
快速检查显示 0.5 会很大,-0.5 会很小,这意味着这是一个完美的工作scipy.optimize.bisect
。
from scipy.optimize import bisect
lamb = bisect(lambda x: change_scale(y,x).mean(),0.5,-0.5)
为我们提供了 lambda 的完美值。图片看起来像这样
这正是我从那以后所期望的。平均值有点太小了,所以我们把事情调高了一点。现在均值为零,最大值为 1,最小值为 -1。
作为最后的健全性检查,我们可以绘制我们实际应用于我们的值的函数:
推荐阅读
- ruby-on-rails - Rails Administrate:如何更改界面语言
- android - kotlin:分配类数据成员创建问题
- python - Nipype自定义界面未显示输出
- android - 数据填充在不正确的类别中,Android 嵌套 Recyclerview
- python-3.x - 使用 python pandas asFreq() 填充日期始终返回 1970-01-01
- kotlin - 列出 Kotlin 类中的所有属性,不包括具有自定义 getter 的属性
- yaml - 如何比较两个 OpenAPI 3.x YAML 文件?
- sql - postgres 查询写作从我的表中查找哪个人超过了计划的工作时间
- .net - 在 WinForms WebBrowser 控件中设置常规文本大小选项
- android - 在图像上叠加透明视频并在 android 中使用 FFmpeg 导出为 GIF