views:

1400

answers:

2

After doing some processing on an audio or image array, it needs to be normalized within a range before it can be written back to a file. This can be done like so:

# 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)

Is there a less verbose, convenience function way to do this? matplotlib.colors.Normalize() doesn't seem to be related.

+3  A: 

You can use the "i" (as in idiv, imul..) version, and it doesn't look half bad:

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

For the other case you can write a function to normalize an n-dimensional array by colums:

def normalize_columns(arr):
    rows, cols = arr.shape
    for col in xrange(cols):
        arr[:,col] /= abs(arr[:,col]).max()
kaizer.se
Can you clarify this? The parentheses make it behave differently than without?
endolith
parantheses don't change anything. the point was to use `/=` instead of `= .. / .. `
kaizer.se
Oh, you just both answered with the same thing at the same time?
endolith
@endolith: I think I was first, but that doesn't matter. Accept the answer you like the most.
kaizer.se
+4  A: 
audio /= np.max(np.abs(audio),axis=0)
image *= (255.0/image.max())

Using /= and *= allows you to eliminate an intermediate temporary array, thus saving some memory. Multiplication is less expensive than division, so

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

is marginally faster than

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

Since we are using basic numpy methods here, I think this is about as efficient a solution in numpy as can be.

unutbu
Why is multiplication less expensive than division?
endolith
I don't know exactly why. However, I am confident of the claim, having checked it with timeit. With multiplication, you can work with one digit at a time. With division, especially with large divisors, you have to work with many digits, and "guess" how many times the divisor goes into the dividend. You end up doing many multiplication problems to solve one division problem. The computer algorithm for doing division may not be the same as human long division, but nevertheless I believe it's more complicated than multiplication.
unutbu