Normalize values between -1 and 1 inclusive - python

I am trying to generate a .wav file in python using Numpy. I have voltages ranging between 0-5V and I need to normalize them between -1 and 1 to use them in a .wav file.
I have seen this website which uses numpy to generate a wav file but the algorithm used to normalize is no long available.
Can anyone explain how I would go about generating these values in Python on my Raspberry Pi.

isn't this just a simple calculation? Divide by half the maximum value and minus 1:
In [12]: data=np.linspace(0,5,21)
In [13]: data
Out[13]:
array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ,
2.25, 2.5 , 2.75, 3. , 3.25, 3.5 , 3.75, 4. , 4.25,
4.5 , 4.75, 5. ])
In [14]: data/2.5-1.
Out[14]:
array([-1. , -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0. ,
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

The following function should do what you want, irrespective of the range of the input data, i.e., it works also if you have negative values.
import numpy as np
def my_norm(a):
ratio = 2/(np.max(a)-np.min(a))
#as you want your data to be between -1 and 1, everything should be scaled to 2,
#if your desired min and max are other values, replace 2 with your_max - your_min
shift = (np.max(a)+np.min(a))/2
#now you need to shift the center to the middle, this is not the average of the values.
return (a - shift)*ratio
my_norm(data)

You can use the fit_transform method in sklearn.preprocessing.StandardScaler. This method will remove the mean from your data and scale your array to unit variance (-1,1)
from sklearn.preprocessing import StandardScaler
data = np.asarray([[0, 0, 0],
[1, 1, 1],
[2,1, 3]])
data = StandardScaler().fit_transform(data)
And if you print out data, you will now have:
[[-1.22474487 -1.41421356 -1.06904497]
[ 0. 0.70710678 -0.26726124]
[ 1.22474487 0.70710678 1.33630621]]

Related

What exactly A[:, state] means in the python?

What exactly this the following line means?
# p=T[:, state] what does this means?
# Here is the complete code
import numpy as np
T = np.array([ [ 0.40, 0.56, 0.03, 0.01],
[0.45, 0.51, 0.04, 0.00],
[0.25, 0.25, 0.25, 0.25 ],
[0.00, 0.00, 0.01, 0.99 ]])
xk = np.arange(len(T))
def gen_sample(state):
return np.random.choice(xk, 1, p=T[:, state])
I understand it takes the transition matrix but what does " : " and "state" mean?
T is a numpy array:
In [38]: T
Out[38]:
array([[0.4 , 0.56, 0.03, 0.01],
[0.45, 0.51, 0.04, 0. ],
[0.25, 0.25, 0.25, 0.25],
[0. , 0. , 0.01, 0.99]])
T[..] is indexing; in this case is selects a column of the array:
In [39]: T[:,0]
Out[39]: array([0.4 , 0.45, 0.25, 0. ])
In [40]: T[:,3]
Out[40]: array([0.01, 0. , 0.25, 0.99])
Spend some time to read the numpy basics. Indexing an array is a very basic operation.
In this case, : means all "row"s in this matrix are selected and state is the "column" index param.
Has many possibles to access an array, and [start:end] is by slicing.
Consider:
a = np.array([0,1,2,3,4])
if you try a[1:4] it's return a slice of a starting at second position ending at fifth (remember that python indexes starts on zero)
By default, if you not pass a start and/or end position, they use 0 to start and len(a) to end.
Learn mor about on this w3schools tutorial

turning a list of numpy.ndarray to a matrix in order to perform multiplication

i have vectors of this form :
test=np.linspace(0,1,10)
i want to stack them horizontally in order to make a matrix .
problem is that i define them in a loop so the first stack is between an empty matrix and the first column vector , which gives the following error:
ValueError: all the input arrays must have same number of dimensions
bottom line - i have a for loop that with every iteration creates a vector p1 and i want to add it to a final matrix of the form :
[p1 p2 p3 p4] which i could then do matrix operations on such as multiplying by the transposed etc
If you've got a list of 1D arrays that you want horizontally stacked, you could convert them all to column first, but it's probably easier to just vertically stack them and then transpose:
In [6]: vector_list = [np.linspace(0, 1, 10) for _ in range(3)]
In [7]: np.vstack(vector_list).T
Out[7]:
array([[0. , 0. , 0. ],
[0.11111111, 0.11111111, 0.11111111],
[0.22222222, 0.22222222, 0.22222222],
[0.33333333, 0.33333333, 0.33333333],
[0.44444444, 0.44444444, 0.44444444],
[0.55555556, 0.55555556, 0.55555556],
[0.66666667, 0.66666667, 0.66666667],
[0.77777778, 0.77777778, 0.77777778],
[0.88888889, 0.88888889, 0.88888889],
[1. , 1. , 1. ]])
How did you get this dimension error? What does empty array have to do with it?
A list of arrays of the same length:
In [610]: alist = [np.linspace(0,1,6), np.linspace(10,11,6)]
In [611]: alist
Out[611]:
[array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]),
array([10. , 10.2, 10.4, 10.6, 10.8, 11. ])]
Several ways of making an array from them:
In [612]: np.array(alist)
Out[612]:
array([[ 0. , 0.2, 0.4, 0.6, 0.8, 1. ],
[10. , 10.2, 10.4, 10.6, 10.8, 11. ]])
In [614]: np.stack(alist)
Out[614]:
array([[ 0. , 0.2, 0.4, 0.6, 0.8, 1. ],
[10. , 10.2, 10.4, 10.6, 10.8, 11. ]])
If you want to join them in columns, you can transpose one of the above, or use:
In [615]: np.stack(alist, axis=1)
Out[615]:
array([[ 0. , 10. ],
[ 0.2, 10.2],
[ 0.4, 10.4],
[ 0.6, 10.6],
[ 0.8, 10.8],
[ 1. , 11. ]])
np.column_stack is also handy.
In newer numpy versions you can do:
In [617]: np.linspace((0,10),(1,11),6)
Out[617]:
array([[ 0. , 10. ],
[ 0.2, 10.2],
[ 0.4, 10.4],
[ 0.6, 10.6],
[ 0.8, 10.8],
[ 1. , 11. ]])
You don't specify how you create the 'empty array' and how you attempt to stack. I can't exactly recreate the error message (full traceback would have helped). But given that message did you check the number of dimensions of the inputs? Did they match?
Array stacking in a loop is tricky. You have to pay close attention to the shapes, especially of the initial 'empty' array. There isn't a close analog to the empty list []. np.array([]) is 1d with shape (1,). np.empty((0,6)) is 2d with shape (0,6). Also all the stacking functions create a new array with each call (non operate in-place), so they are inefficient (compared to list append).

Remove specific values from dataframe

I have the following correlation matrix:
symbol abc xyz ghj
symbol
abc 1 0.1 -0.2
xyz 0.1 1 0.3
ghj -0.2 0.3 1
I need to be able to find the standard deviation for the whole dataframe but that has to exclude the perfect correlation values, ie: the standard deviation must not take into account abc:abc, xyz:xyz, ghj:ghj
I am able to get the standard deviation for the entire dataframe using:
df.stack().std()
But this takes into account every single value which is not correct. The standard deviation should not include row/column combinations where an item is being correlated to itself (ie: 1). Is there a way to remove abc:abc, xyz:xyz, ghj:ghj. Then calculate the standard deviation.
Perhaps converting it to a dict or something?
If you use numpy you can utilize np.extract and np.std:
In [61]: import numpy as np
In [62]: a = np.array([[ 1. , 0.1, -0.2],
[ 0.1, 1. , 0.3],
[-0.2, 0.3, 1. ]])
In [63]: a
Out[63]:
array([[ 1. , 0.1, -0.2],
[ 0.1, 1. , 0.3],
[-0.2, 0.3, 1. ]])
In [64]: calc_std = np.std(np.extract(a != 1, a))
In [65]: calc_std
Out[65]: 0.20548046676563256
np.extract(a != 1, a)) returns an array containing each element of a which is not equal to 1.
The returned array looks like this:
In [66]: np.extract(a != 1, a)
Out[66]: array([ 0.1, -0.2, 0.1, 0.3, -0.2, 0.3])
After this extraction you can easily calculate the standard deviation with np.std().

interpolate linear array to non linear array using python numpy or scipy

i have to arrays:
a linear one;
x = array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2, 1.3, 1.4])
And a corresponding result which is a non-linear one;
y = array([ 13.07, 13.7 , 14.35, 14.92, 15.5 , 16.05, 16.56, 17.12,
17.62, 18.08, 18.55, 19.02, 19.45, 19.88, 20.25])
Now: I want to convert y to a linearly spaced array and find the corresponding interpolated values of x.
i.e. find x when
y = array([ 13. , 13.5, 14. , 14.5, 15. , 15.5, 16. , 16.5, 17. , 17.5, 18. , 18.5, 19. , 19.5, 20. ])
Thanks in advance.
I use the following method using the interp function in numpy:
ynew = np.linspace(np.min(y), np.max(y), len(y))
xnew = np.interp(ynew, y, x)
i.e. exchanging x and y in the np.interp function.
Is this always correct ? or will it break down for some condition.
Unless I'm missing something, this case calls for a simple invocation of numpy.interp. You want to predict x from y which is the reverse of how people usually do their variable definitions, but other than that wrinkle, all you need is:
import numpy as np
x = np.array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2, 1.3, 1.4])
y = np.array([ 13.07, 13.7 , 14.35, 14.92, 15.5 , 16.05, 16.56, 17.12,
17.62, 18.08, 18.55, 19.02, 19.45, 19.88, 20.25])
ynew = np.array([ 13. , 13.5, 14. , 14.5, 15. , 15.5, 16. , 16.5, 17. , 17.5, 18. , 18.5, 19. , 19.5, 20. ])
xnew = np.interp(ynew, y, x)
print xnew
Which gives as ouput:
[ 0. 0.06825397 0.14615385 0.22631579 0.3137931 0.4
0.49090909 0.58823529 0.67857143 0.776 0.8826087 0.9893617
1.09574468 1.21162791 1.33243243]

setting an array element with a sequence

So I'm not the best at python but I need to create this program for one of my courses and I keep getting this error.
Basically I have w_array = linspace(0.6, 1.1, 11), then I have zq = array([1, 1, w_array, 1])
and it comes up with the error message:
ValueError: setting an array element with a sequence.
the basic function of the code is to take a bezier spline aerofoil, with control points and weights, run the data in xfoil and print cd and cl values, but this addition is to show a graph of the range of cd for a certain control point.
hope it makes sense, any help would be greatly appreciated.
If you want zq be an array containing both ints and lists, use parameter dtype:
In [300]: zq = array([1, 1, w_array, 1], dtype=object)
In [301]: zq
Out[301]:
array([1, 1,
array([ 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 , 0.95, 1. ,
1.05, 1.1 ]),
1], dtype=object)
Is this your intended result?
In [2]:
numpy.hstack((1,1,numpy.linspace(0.6,1.1,11),1))
Out[2]:
array([ 1. , 1. , 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 ,
0.95, 1. , 1.05, 1.1, 1. ])
You probably want the resulting array to have float64 dtypes rather than object, a mixed bag of dtypes, as #DSM pointed out.

Categories