代码之家  ›  专栏  ›  技术社区  ›  endolith

如何将numpy数组规范化为一定范围内?

  •  93
  • endolith  · 技术社区  · 15 年前

    在对音频或图像数组进行一些处理之后,需要在一个范围内对其进行规范化,然后才能将其写回文件。可以这样做:

    # Normalize audio channels to between -1.0 and +1.0
    audio[:,0] = audio[:,0]/abs(audio[:,0]).max()
    audio[:,1] = audio[:,1]/abs(audio[:,1]).max()
    
    # Normalize image to between 0 and 255
    image = image/(image.max()/255.0)
    

    是否有一种不那么冗长、方便的函数方法来实现这一点? matplotlib.colors.Normalize() 似乎没有关系。

    6 回复  |  直到 6 年前
        1
  •  105
  •   unutbu    15 年前
    audio /= np.max(np.abs(audio),axis=0)
    image *= (255.0/image.max())
    

    使用 /= *= 允许您消除中间临时数组,从而节省一些内存。乘法比除法便宜,所以

    image *= 255.0/image.max()    # Uses 1 division and image.size multiplications
    

    image /= image.max()/255.0    # Uses 1+image.size divisions
    

    因为我们在这里使用的是基本的numpy方法,所以我认为这是numpy中最有效的解决方案。

        2
  •  35
  •   cjohnson318    11 年前

    您也可以使用 sklearn . 其优点是,除了意味着将数据居中之外,您还可以调整标准偏差的规格化,并且您可以在任意轴上、通过特性或通过记录执行此操作。

    from sklearn.preprocessing import scale
    X = scale( X, axis=0, with_mean=True, with_std=True, copy=True )
    

    关键字参数 axis , with_mean , with_std 是不言自明的,并以默认状态显示。争论 copy 如果设置为,则就地执行操作 False . 文档 here .

        3
  •  31
  •   user2821    6 年前

    如果数组同时包含正数据和负数据,我将使用:

    import numpy as np
    
    a = np.random.rand(3,2)
    
    # Normalised [0,1]
    b = (a - np.min(a))/np.ptp(a)
    
    # Normalised [0,255] as integer
    c = 255*(a - np.min(a))/np.ptp(a).astype(int)
    
    # Normalised [-1,1]
    d = 2*(a - np.min(a))/np.ptp(a)-1
    

    另外,值得一提的是,即使这不是OP的问题, standardization :

    e = (a - np.mean(a)) / np.std(a)
    
        4
  •  10
  •   u0b34a0f6ae    15 年前

    您可以使用“i”(如IDIV、IMUL等)版本,而且看起来还不错:

    image /= (image.max()/255.0)
    

    对于另一种情况,您可以编写一个函数来按列规范化N维数组:

    def normalize_columns(arr):
        rows, cols = arr.shape
        for col in xrange(cols):
            arr[:,col] /= abs(arr[:,col]).max()
    
        5
  •  3
  •   Pantelis    6 年前

    一个简单的解决方案是使用sklearn.preprocessing库提供的定标器。

    scaler = sk.MinMaxScaler(feature_range=(0, 250))
    scaler = scaler.fit(X)
    X_scaled = scaler.transform(X)
    # Checking reconstruction
    X_rec = scaler.inverse_transform(X_scaled)
    

    错误x_rec-x将为零。您可以根据需要调整功能范围,甚至可以使用标准缩放器sk.standardscaler()。

        6
  •  2
  •   srdg    6 年前

    我试图跟踪 this 然后得到了错误

    TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''
    

    这个 numpy 我试图规范化的数组是 integer 数组。似乎他们不赞成在版本中进行类型转换> 1.10 你必须使用 numpy.true_divide() 解决这个问题。

    arr = np.array(img)
    arr = np.true_divide(arr,[255.0],out=None)
    

    img 是一个 PIL.Image 对象。