Python:归一化多维数组

3 投票
1 回答
3018 浏览
提问于 2025-04-18 04:05

我有一段代码可以生成和导出12个立体声WAV文件。

目前我只是这样做:

for i in range(0,12):
    filename = "out_%d.wav" % i
    L = ... some list of floats between -1.0 and +1.0 ...
    R = ... similarly ...

    exportWAV(filename,L,R)

但是音量太小了。

我需要做的是找出所有左声道(L)和右声道(R)中的最大音量,然后把所有的L和R都除以这个最大音量。这样我的所有数值就会在-1到1之间。

这并不是一个难事,我可以写一些不太好看的代码来完成它。

但是,怎么才能写得更简洁呢?

我应该能用几行代码做到,类似于:

all_LR = ''
all_file = ''

for i in range(0,12):
    filename = ...
    L, R = ...

    all_LR += (L,R)
    all_file += filename

maxVal = max( abs(all_LR) )
all_LR /= maxVal

for file,L,R in zip( all_file, all_LR ):
    exportWAV(filename L,R)

但我不知道怎么把这个伪代码变成有效的Python代码。因为abs和max函数不能直接处理一个包含元组的数组,而每个元组里的元素又是一个浮点数数组。

我感觉自己只是为了省几行代码而把事情搞得更复杂了。

编辑:感谢下面的回答,我现在有了以下可以工作的代码:

all_LR = []

for i in range(0,12):
    print "Processing %d" % i

    hrtf_file = hrtf_path + "/%02d.wav" % (i+1)
    shep_file = shepard_path + "/shepard_%02d.WAV" % i

    L, R = import_WAV( hrtf_file )
    shep = import_WAV( shep_file )

    out_L = np.convolve(shep,L)
    out_R = np.convolve(shep,R)

    #out_LR = np.array( out_L, out_R )
    out_LR = (list(out_L), list(out_R))
    all_LR.append(out_LR)
    #np.append( all_LR, out_LR )

np_array = np.array(all_LR)

amp_max = np.amax( np.fabs(np_array) )
print( "AmpMAX: %f" % amp_max )

np_array /= amp_max

for i in range(0,12):
    out_file = out3d_path + "/s3D_%02d.WAV" % i
    print out_file

    L,R = np_array[i]

    export_WAV( out_file, L, R )

1 个回答

3

如果你能把你的数据转换成 numpy.arrays,那么你就可以使用 numpy.amaxnumpy.fabs,像下面这样。

import numpy as np

a = np.array([(1, 2), (-3, 4), (-2, 2), (0, 1), (1, 3)])

a_abs = np.fabs(a)
print(a_abs)
# [[ 1.  2.]
#  [ 3.  4.]
#  [ 2.  2.]
#  [ 0.  1.]
#  [ 1.  3.]]

a_max = np.amax(a_abs)

print(a_max)
# 4.0

np.fabs 会返回一个和原数组形状一样的新数组,不过每个元素都是原来元素的绝对值,适用于多维数组。

np.amax 会返回数组中的最大值。如果你使用一个关键字参数选择了 axis(比如 np.amax(a, axis=0)),那么它会沿着那个 axis 进行计算。不过,axis 的默认值是 None,这意味着它会对整个数组进行扁平化处理后再找最大值。

撰写回答