extract value of a numeric array function in numpy - python

If I define a function whit two array, for instance like this:
from numpy import *
x = arange(-10,10,0.1)
y = x**3
How can I extract the value of y(5.05) interpolating the value of the two closer point y(5) and y(5.1)? Now if I want find that value, I use this method:
y0 = y[x>5][0]
And I should obtain the value of y for x=5.1, but I think that exist better methods, and probably they are the correct ones.

There's numpy.interp, if linear interpolation will suffice:
>>> import numpy as np
>>> x = np.arange(-10, 10, 0.1)
>>> y = x**3
>>> np.interp(5.05, x, y)
128.82549999999998
>>> 5.05**3
128.787625
And there are a bunch of tools in scipy for interpolation [docs]:
>>> import scipy.interpolate
>>> f = scipy.interpolate.UnivariateSpline(x, y)
>>> f
<scipy.interpolate.fitpack2.LSQUnivariateSpline object at 0xa85708c>
>>> f(5.05)
array(128.78762500000025)

There's a function for this in numpy/scipy..
import numpy as np
np.interp(5.05, x, y)

Related

contour graph tuple index out of range

I'm trying to use the contour function of matplotlib.pyplot. I get an error tuple index out of range.
import numpy as np
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
import math
x, y = make_regression(n_samples=100, n_features=1, noise=10)
y = y + abs(y/2)
thetaInitial = np.random.randn(3,1)
thetaFinal = np.random.randn(3,1)
def f(x): return x**2+x
xmesh, ymesh = np.meshgrid(x, y)
print("x :", xmesh.shape); print("y :", ymesh.shape); print("z: ", z.shape)
z = f(np.array([xmesh, ymesh]))
plt.contour(X=xmesh, Y=ymesh, Z= z, levels=20)
­
tuple index out of range
There are a few problems that need to be addressed:
Please, read the documentation to obtain contour plots with `help(plt.contour).
from the docs, you'll see that x, y needs to be monotonically sorted. You can achieve that with np.sort(x.reshape(len(x))).
You evaluated your function with z = f(np.array([xmesh, ymesh])), obtaining an array with shape (2, 100, 100). From the docs, Z must be a 2D array. So you have to execute plt.contour(X=xmesh, Y=ymesh, Z=z[0]) or z[1].

Unpacking iteratively a tuple? A tuple of floats I'd like to pass to 2 params in a function

import numpy as np
x = ['0.01107', '0.02314', '0.03321', '0.04428', '0.08035']
y = ['0.8864', '0.6703', '0.4542', '0.3382', '0.2321']
hypotenuse_array = np.hypot(x, y)
print("Hypotenuse_array = ", hypotenuse_array)
Doesn't work because of float I think?
a_zip = zip(x, y)
zipped = list(a_zip)
print(zipped)
How to pass X & Y zipped list to np.hypot on loop?
I think the first issue is that you are using strings in the arrays of x and y. If you try to use numbers whith the following code, it will produce a result. But I am not sure if that is what you want to achieve though.
import numpy as np
x = [0.01107, 0.02314, 0.03321, 0.04428, 0.08035]
y = [0.8864, 0.6703, 0.4542, 0.3382, 0.2321]
hypotenuse_array = np.hypot(x, y)
print("Hypotenuse_array = ", hypotenuse_array)
Convert string arrays to float.
import numpy as np
x = ['0.01107', '0.02314', '0.03321', '0.04428', '0.08035']
y = ['0.8864', '0.6703', '0.4542', '0.3382', '0.2321']
# convert x & y to numpy float as we pass them to hypot
hypotenuse_array = np.hypot(np.array(x).astype(np.float), np.array(y).astype(np.float))
print("Hypotenuse_array = ", hypotenuse_array)
# Output: array([0.88646912, 0.6706993 , 0.4554125 , 0.34108644, 0.2456146 ])

How to take out x and y from my list so I can use it to create a graph

So I made my list but after that I don't know how to take out of it my x and y so I can use it later to create a graph
import random
import numpy as np
import matplotlib.pyplot as plt
tabuletson = []
for i in range(0, 10):
x = round(random.uniform(-1000,1000),2)
y = (2*x+1)
tabuletson.append([x,y])
print(tabuletson)
wielomian = np.poly1d(np.polyfit(x,y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(x,y)
plt.plot(linia,wielomian(linia))
plt.show()
All you have to do is to add one line of code after and outside your for loop. This command will create two lists containing x and y values. You can use the same variable names x and y.
x, y = zip(*tabuletson)
I think that this is a better way to do what you want according of how plt.scatter and plt.plot work. Hope it works as you want!
import random
import numpy as np
import matplotlib.pyplot as plt
x = []; y = []
for i in range(10):
x.append(round(random.uniform(-1000,1000),2))
y.append(2*x[i]+1)
wielomian = np.poly1d(np.polyfit(x,y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(x,y)
plt.plot(linia,wielomian(linia))
plt.show()
The np.polyfit and plt.scatter functions you are using require separate lists of X and Y coordinates.
Try:
import random
import numpy as np
import matplotlib.pyplot as plt
tabuletson_x = []
tabuletson_y = []
for i in range(0, 10):
x = round(random.uniform(-1000,1000),2)
y = (2*x+1)
tabuletson_x.append(x)
tabuletson_y.append(y)
print(tabuletson_x)
print(tabuletson_y)
wielomian = np.poly1d(np.polyfit(tabuletson_x,tabuletson_y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(tabuletson_x,tabuletson_y)
plt.plot(linia,wielomian(linia))
plt.show()
Note: referencing x and y after the for cycle will give you the last values from the randomly generated list:
list of x vals: [-8.78, 554.81, -693.22, 955.8, 88.95, 235.55, -108.67, -804.08, 494.65, 754.58]
list of y vals: [-16.56, 1110.62, -1385.44, 1912.6, 178.9, 472.1, -216.34, -1607.16, 990.3, 1510.16]
x: 754.58
y: 1510.16
For more info:
PyPlot Scatter documentation
PolyFit documentation
Your x and y are stored in your list tabuletson. Like this: [[x0,y0], [x1,y1], ..., [x,y]]
So you can, for example, get the value of x1 and y1 with x1 = tabuletson[1][0] and y1 = tabuletson[1][1]
Is that your question ?
tabuletson = np.array(tabuletson)
X, Y = tabuletson[:,0], tabuletson[:,1]
X will have all your xs from list
And, Y will have all your ys from list

sorting via argsort - generalization to 2d matrices

For sorting a numpy via argsort, we can do:
import numpy as np
x = np.random.rand(3)
x_sorted = x[np.argsort(x)]
I am looking for a numpy solution for the generalization to two or higher dimensions.
The indexing as in the 1d case won't work for 2d matrices.
Y = np.random.rand(4, 3)
sort_indices = np.argsort(Y)
#Y_sorted = Y[sort_indices] (what would that line be?)
Related: I am looking for a pure numpy answer that addresses the same problem as solved in this answer: https://stackoverflow.com/a/53700995/2272172
Use np.take_along_axis:
import numpy as np
np.random.seed(42)
x = np.random.rand(3)
x_sorted = x[np.argsort(x)]
Y = np.random.rand(4, 3)
sort_indices = np.argsort(Y)
print(np.take_along_axis(Y, sort_indices, axis=1))
print(np.array(list(map(lambda x, y: y[x], np.argsort(Y), Y)))) # the solution provided
Output
[[0.15599452 0.15601864 0.59865848]
[0.05808361 0.60111501 0.86617615]
[0.02058449 0.70807258 0.96990985]
[0.18182497 0.21233911 0.83244264]]
[[0.15599452 0.15601864 0.59865848]
[0.05808361 0.60111501 0.86617615]
[0.02058449 0.70807258 0.96990985]
[0.18182497 0.21233911 0.83244264]]

How to do the loop along a 3D vector with a known length by python

I have done a point filter programme in a 3D plane, but I need to do a loop along a known 3D normal vector with a known length. Many thanks for the help.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
point = sta[10] #starting points
normal = axe[10] #normal vector
d = -point.dot(normal)
# create x,y
xx, yy = np.meshgrid(np.linspace(-3.,-2.,101), np.linspace(-11.,-10.,101))
# calculate corresponding z
z = (-normal[0] * xx - normal[1] * yy - d) * 1. /normal[2]
f=[]
for i in xrange(len(xx)-1):
for j in xrange(len(xx)-1):
if (xx[i][j]-sta[10][0])**2 + (yy[i][j]-sta[10][1])**2 + (z[i][j]-sta[10][2])**2 > float(rad[0])**2:
xx[i][j]=NaN
yy[i][j]=NaN
z[i][j]=NaN
Since you're using meshgrid and xx, yy and z have the same shape, numpy's broadcasting policy will automatically do what you need. Try this:
invalid = (xx-sta[10,0])**2 + (yy-sta[10,1])**2 + (z-sta[10,2])**2 > float(rad[0])**2
xx[invalid]=np.NaN
yy[invalid]=np.NaN
z[invalid]=np.NaN
It creates a boolean mask invalid which contains True for all entries that satisfy the condition. You can then use this mask to set the corresponding values to NaN.
Note that you can use tuples to index numpy arrays. I.e. myArray[a][b] is equivalent to myArray[a, b].
Also note that I assumed you excluded the last entries by accident. If it was on purpose that you used xrange(len(xx)-1) rather than xrange(len(xx)), it is getting a bit uglier and you have to do it like this:
invalid = (xx[:-1,:-1]-sta[10,0])**2 + (yy[:-1,:-1]-sta[10,1])**2 + (z[:-1,:-1]-sta[10,2])**2 > float(rad[0])**2
xx[:-1,:-1][invalid]=np.NaN
yy[:-1,:-1][invalid]=np.NaN
z[:-1,:-1][invalid]=np.NaN

Categories

Resources