Filling up a NumPy array based on the index of the element - python

Assume:
u = 1.2
d = 0.8
n = 3
I was wondering how I can get an array with 3 (n) elements where the value of each element is:
The solution to variables above would be:
[1.2^2 + 0.8^0, 1.2^1 + 0.8^1, 1.2^0 + 0.8^1]
Thanks!

You could achieve this with Basic slicing and indexing.
import numpy as np
u=1.2
d=0.8
n=3
array=np.zeros(n)
for i in range(n):
if i + 1 <= n:
array[i:n]=u**(n-i-1)
array[i:n] =d**(i)

Related

More information on output array with equation and indicies

I have a math function whose output is defined by two variables, x and y.
The function is e^(x^3 + y^2).
I want to calculate every possible integer combination between 1 and some defined integer for x and y, and place them in an array so that each output is aligned with the cooresponding x value and y value index. So something like:
given:
x = 3
y = 5
output would be an array like this:
f(1,1) f(1,2) f(1,3)
f(2,1) f(2,2) f(2,3)
f(3,1) f(3,2) f(3,3)
f(4,1) f(4,2) f(4,3)
f(5,1) f(5,2) f(5,3)
I feel like this is an easy problem to tackle but I have limited knowledge. The code that follows is the best description.
import math
import numpy as np
equation = math.exp(x**3 + y**2)
#start at 1, not zero
i = 1
j = 1
#i want an array output
output = []
#function
def shape_f (i,j):
shape = []
output.append(shape)
while i < x + 1:
while j < y +1:
return math.exp(i**3 + j**2)
#increase counter
i = i +1
j = j +1
print output
I've gotten a blank array recently but I have also gotten one value (int instead of an array)
I am not sure if you have an indentation error, but it looks like you never do anything with the output of the function shape_f. You should define your equation as a function, rather than expression assignment. Then you can make a function that populates a list of lists as you describes.
import math
def equation(x, y):
return math.exp(x**3 + y**2)
def make_matrix(x_max, y_max, x_min=1, y_min=1):
out = []
for i in range(x_min, x_max+1):
row = []
for j in range(y_min, y_max+1):
row.append(equation(i, j))
out.append(row)
return out
matrix = make_matrix(3, 3)
matrix
# returns:
[[7.38905609893065, 148.4131591025766, 22026.465794806718],
[8103.083927575384, 162754.79141900392, 24154952.7535753],
[1446257064291.475, 29048849665247.426, 4311231547115195.0]]
We can do this very simply with numpy.
First, we use np.arange to generate a range of values from 0 (to simplify indexing) to a maximum value for both x and y. We can perform exponentiation, in a vectorised manner, to get the values of x^3 and y^2.
Next, we can apply np.add on the outer product of x^3 and y^3 to get every possible combination thereof. The final step is taking the natural exponential of the result:
x_max = 3
y_max = 5
x = np.arange(x_max + 1) ** 3
y = np.arange(y_max + 1) ** 2
result = np.e ** np.add.outer(x, y)
print(result[2, 3]) # e^(2 ** 3 + 3 ** 2)
Output:
24154952.753575277
A trivial solution would be to use the broadcasting feature of numpy with the exp function:
x = 3
y = 5
i = np.arange(y).reshape(-1, 1) + 1
j = np.arange(x).reshape(1, -1) + 1
result = np.exp(j**3 + y**2)
The reshape operations make i into a column with y elements and j into a row with x elements. Exponentiation does not change those shapes. Broadcasting happens when you add the two arrays together. The unit dimensions in one array get expanded to the corresponding dimension in the other. The result is a y-by-x matrix.

Matlab to Python

I have a simple code in MATLAB which I am trying to translate to python, but I am stuck in a simple for loop:
Here is the situation:
Matlab
f0 = constant
fn = (nx1) matrix
b = (nx1) matrix
d and x are constant
mthd = 1 or 2
s = 1:-0.1:0.1;
for i = 1:10
f = fn * s(i)
switch mthd
case 1
v(:,i) = d *(1 + 1./b.*(f0./f)).^x
case 2
v(:,i) = log(f0./f)./b;
v(:,i) = v./(1+v)
end
v(1,:) = min(vp(2,:));
The output in Matlab results v with nx1 matrix
Assuming it is a simple equation with element wise operation in matlab,
I went ahead and wrote a code in python like this:
s = np.linspace(1,0.1,num=10)
for i in range(1,11)
f = fn * s[i]
if mthd ==1:
v = d *(1 + 1/b*(f0/f))^x
elif mthd ==2:
v = log(f0/f)/b;
v = v/(1+v)
Clearly, this is not the right one and I get stuck right from f = fn* s[i]
Any suggestion in this conversion will be of great help.
Thank you
Clearly this is not the right one and I get stuck right from f = fn* s[i]
What error message are you getting here? Make sure your vectors fn and b are numpy arrays and not lists.
for i in range(1,11)
Python uses zero indexing, whereas Matlab uses 1-indexing. Therefore your for loop should use for i in range(10), which iterates from 0 to 9 instead of 1 to 10.
v = d *(1 + 1/b*(f0/f))^x
Assuming fn and b are numpy arrays in your Python implementation, if you really want this to mirror the Matlab code you can still use indexing such as v[:,i]. However you need to initialize v as a numpy array with the correct size first.
v = log(f0/f)/b;
You probably want np.log here.
Hopefully this is helpful, let me know if you still have questions. You may also find this website helpful.
The code block below should be closer to what you want. Here are a few things to look out for:
Phyton arrays are indexed from 0. In base Python you handle powers with ** e.g. 2 ** 2 equals 4
When performing scalar multiplication and divide of arrays, better to use np.multiply and np.divide
Use np.log for logarithm and np.power for exponentiation with numpy matrices.
Use np.add to add a scalar to a numpy array.
import numpy as np
f0 = 5 # constant
fn = np.matrix([[5], [4], [3], [2], [1]]) # 5 x 1 matrix
b = np.matrix([[9], [8], [7], [6], [5]]) # 5 x 1 matrix
# d and x are constant
d = 4
x = 8
# mthd = 1 or 2
mthd = 1
s = np.linspace(1,0.1,num=10)
# python arrays are indexed from 0
for i in range(0,len(s)):
f = fn * s[i]
if mthd == 1:
v = np.power(np.multiply(d, (1 + np.divide(1., np.multiply
(b, np.divide(f0, f) ) ) ) ), x)
elif mthd ==2:
v = np.divide(np.log(np.divide(f0,f)), b);
v = np.divide(v, (np.add(1, v)) )

The long integer when using NumPy

I have the following simple codes for the sum of two vectors.
However, I get the wrong results when I use NumPy.
The results of the codes is as follows:
In [12]: %run -i test.py
The last 2 elements of the sum [7980015996L, 7992002000L]
The last 2 elements of the sum [-609918596 -597932592]
It's not a long integer, Why?
import numpy as np
def numpysum(n):
a = np.arange(n) ** 2
b = np.arange(n) ** 3
c = a + b
return c
def pythonsum(n):
a = range(n)
b = range(n)
c = []
for i in range(len(a)):
a[i] = i ** 2
b[i] = i ** 3
c.append(a[i] + b[i])
return c
size = 2000
c = pythonsum(size)
print "The last 2 elements of the sum", c[-2:]
c = numpysum(size)
print "The last 2 elements of the sum", c[-2:]
Plain Python integers can grow arbitrarily large. Numpy integers cannot; they are limited by the size of the data type. If they get too big, they will wrap around and become negative. It looks like your array dtype is probably int32, which overflows and results in negative results. You can get the correct results in this case by using int64:
a = np.arange(n, dtype=np.int64) ** 2
b = np.arange(n, dtype=np.int64) ** 3
However, it will still overflow eventually (if you make size larger). You could also use float64, which allows even larger numbers, but then you will lose precision.
The cap on integer sizes is the price you pay for the speed numpy gives you.

Linear algebra on python (gaussian elimination)

I am a newbie to python and I came across some issues while I was working on Gaussian elimination using python. I got the error message:
IndexError: index 4 is out of bounds for axis 0 with size 4.
How should I correct it?
A = array( [[3,-1,-1,0,0,0],
[-1,4,-1,-1,0,0],
[0,0,-1,-1,4,-1],
[0,0,0,-1,-1,3]], float)
v = array([5,5,0,0,0,0],float)
N = len(v)
for m in range(N):
Div = A[m,m]
A[m,:]/= Div
v[m]/= Div
for i in range(m + 1, N):
mult= A[i,m]
A[i,:]-= mult*A[m,:]
v[i]-= mult*v[m]
x = empty(N,float)
for m in range(N-1,-1,-1):
x[m] = v[m]
for i in range(m + 1,N):
x[m]-= A[m,i]*x[i]
print(x)
It appears to me that you have a matrix of size 4x6, which means your indices for each dimension of your array go from 0 to 3 and 0 to 5 respectively.
Then you have a for loop going from 0 to range(N), where N is a length of a 6 element array. This is the loop with m as an iterator.
Finally, you have (what I assume is meant to be) an inner loop going from m+1 to N and you use that index in A for the rows:
for i in range(m + 1, N):
mult= A[i,m]
The variable i here will be going to N (which is 6 in this case) each time, but your A matrix can only go 0 to 3 there in the rows index.
In summary:
A is a 4x6 matrix
N is length 6
you are trying to access A[4,m] in the following loop (as well as A[5,m] and A[6,m]:
for i in range(m + 1, N):
mult= A[i,m]
when you can only at most reach A[3,m].
EDIT:
Actually, the error happens a little earlier than I mentioned previously:
for m in range(N):
Div = A[m,m]
Here, A[m,m] will not work for m > 4, but m in range(N) will take m to 5.

Remove elements in a numpy array if they differ of a threshold from each other

I am searching for a more pythonic way to filter the elements in a numpy array. In my case, I have an array composed of N rows and 3 columns.
At the moment, I am doing something like this, but I think there is something that could speed up the 'filtering' of my matrix
Threshold = 0.05
i = 0
while i < M.shape[0]:
j = i + 1
while j < M.shape[0]:
if np.abs(M[i,0]-M[j,0]) <=Threshold and np.abs(M[i,1]-M[j,1]) <=Threshold and M[i,2]==M[j,2]:
M = np.delete(M, (j), axis=0)
j = j + 1
i = i + 1
An example of M is the following:
[43.14562 10.96869 116890560]
The third column is epoch time.

Categories