首页 > 解决方案 > python - 如何更新数组中的每个元素以增加数据的平均值

问题描述

我有在 -4 和 4 之间标准化的音频数据;但是,我需要将波形/数据的“中心”(意思是?)以“1”为中心(请参见附图)

如何操作平均值被转换/转换为〜1的数据列表?同时仍保持 -4 到 4 的正常化

有没有一种简单的方法可以使用 numpy 做到这一点?

在此处输入图像描述

标签: pythonnumpyaudiomeandata-manipulation

解决方案


将来,如果您提供一个可以修补的示例,那就太好了。第二个问题是你没有告诉我们使用什么类型的函数或者它应该保留什么属性。由于显然没有线性函数可以满足您的要求,因此我将使用二次函数。但首先这是我要修补的“声音”

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。

作为最后的健全性检查,我们可以绘制我们实际应用于我们的值的函数:

数据转换功能


推荐阅读