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
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].
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 ])
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
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]]
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