chasep255 chasep255 - 6 months ago 44
Python Question

Numpy converting range of angles from (-Pi, Pi) to (0, 2*Pi)

This seems like it would be very straight forward but I can't seem to figure out how to map angles between -Pi and Pi to the range 0 to 2Pi. I tried using np.select but it freezes my program for some reason. I need the angles in this range since they will be used as training data for a neural net which can not output negative numbers.

audio = wav.read('/home/chase/Desktop/ge.wav')[1].astype(np.float32)
audio = np.mean(audio, 1)
audio /= np.max(np.abs(audio))
audio = np.array([np.fft.rfft(audio[i:i + FRAME_SIZE]) for i in range(0, len(audio) - len(audio) % FRAME_SIZE, FRAME_SIZE)])
audio /= FRAME_SIZE
audio_mag = np.abs(audio)
audio_phase = np.angle(audio)

#this line freezes the program
audio_phase = np.select(audio_phase < 0 , 2 * np.pi + audio_phase, audio_phase)


I need the audio

ssm ssm
Answer

This is typically what I do. Let us say you have these angles:

>>> angles = np.linspace(-np.pi, np.pi, 10)
>>> angles
array([-3.14159265, -2.44346095, -1.74532925, -1.04719755, -0.34906585,
    0.34906585,  1.04719755,  1.74532925,  2.44346095,  3.14159265])

Then, the ones less than zero should be converted to the right value. Something like this:

>>> (2*np.pi + angles) * (angles < 0) + angles*(angles > 0)
array([ 3.14159265,  3.83972435,  4.53785606,  5.23598776,  5.93411946,
    0.34906585,  1.04719755,  1.74532925,  2.44346095,  3.14159265])

Remember that in numpy, you can do logical tests ... angles < 0 is a boolean array. However, 1*(angles < 0) is a numeric array, where True values are mapped to 1 and False values are mapped to 0. You can combine the two concepts to get your answer.

I hope this helps.