How Can I Convert a String to a Ufunc? - python

I am trying to write a simple function that converts an input written in LaTeX to a ufunc that can be read by numpy. So far, I'm testing the function by converting \sin(x) to np.sin(x) (ignoring the conversion from {} to (). I'm not that familiar with ufuncs so I keep running into an error when trying to convert the \sin(x) string to the np.sin(x) ufunc for any given x.
import numpy as np
latexEq = input()
def latexMap(latexEq):
if "\sin" in latexEq:
sinLatex = latexEq.replace("\sin", "np.sin")
else:
pass
return sinLatex
npOutput = np.ufunc(latexMap(latexEq))
print(f"f(x)={numpyOutput}")
Similar to how an integer may be converted into a string str(2), I tried enclosed both sinLatex, latexEq, "np.sin", and npOutput but the error I always receive is
TypeError: cannot create 'numpy.ufunc' instances
Any explanation would be appreciated.

So if you just have npOutput = "np.sin" (without the (x)) you can do
# function_name = getattr(module, function_name_string)
npOutput = getattr(np, npOutput.lstrip("np."))
which gives you the function np.sin. The parentheses have to be gone because otherwise it would be a function call, not a function.

Related

Trying to convert a string into a list in Pandas

I am trying to convert a column, which looks something like this
cleaned
['11-111']
['12-345', '67-789']
['00-000', '01-234']
into a list, since I read that Pandas initially interprets list as strings from this article:
https://towardsdatascience.com/dealing-with-list-values-in-pandas-dataframes-a177e534f173
I using the function mentioned in the article
master["cleaned"] = master["cleaned"].apply(eval)
but I am getting this error
eval() arg 1 must be a string, bytes or code object
I tried looking them up, but I can't figure it out
df.cleaned = pd.eval(df.cleaned)
There doesn't appear to be a built it to deal with failures, so you can make it yourself:
def try_eval(x):
try:
return eval(x)
except:
return x
df.cleaned = df.cleaned.apply(try_eval)
Then you can look for the ones that didn't convert by doing:
df.cleaned[df.cleaned.apply(lambda x: isinstance(x, str))]

How can I add a f(x) as an argument on Python function?

I'm trying to find the maximum of any function f(x) in a certain range and in which x this happens. The arguments of the python function would be (f(x),[a,b]). f(x) being any function and [a,b] the range we will be studying.
For now I've tried a few things but none of them worked. The one I liked the most was a failure because of trying to convert a string onto a float.
def maxf(function,interval):
maxresult = 0
for x in range(interval[0]-1,interval[1]+1):
result=float(function.replace("x",str(x)))
if result >= maxresult:
maxresult = result
maxresultx = x
return maxresult,maxresultx
print(maxf("x**2",[1,3]))
This one returns:
Traceback (most recent call last):
File "main.py", line 10, in <module>
print(maxf("x**2",[1,3]))
File "main.py", line 4, in maxf
result=float(function.replace("x",str(x)))
ValueError: could not convert string to float: '0**2'
I don't know if there is an easier way to do it or how to correct the code so that I can convert that string.
Your problem is that float() accepts a string that already represents a float (eg float("1.23"), not an expression that will result in one (eg float("2**3")). So, you must first evaluate the string.
float(eval("3**2"))
eval() will run any code contained in the string, so don't use it on code you don't trust.
Use this:
def maxf(function,interval):
maxresult = 0
for x in range(interval[0]-1,interval[1]+1):
result=float(function(x))
if result >= maxresult:
maxresult = result
maxresultx = x
return maxresult,maxresultx
print(maxf(lambda x: x**2,[1,3]))
lambda defines a function (an anonymous one) that is passed as parameter, thus maxf can call it as needed.
Python is (also) a functional language, which means that you can use functions as you use ints or floats, etc. A function is just a bunch of callable code, you can associate an identifier to a function or not (just like int values referred by identifiers or as constant in code).
-----EDIT----- suggested by #bacjist
If you don't want to use lambda, then you may define the function as usual:
def f(x):
return x**2
and then call:
print(maxf(f,[1,3]))
The problem is your string is not actually being evaluated. It is just being converted to float so as the error suggests what you are doing is converting "0**2" to float which is not possible what you can do is make use of eval function to evaluate any given string and then compare the result.
You just need to make a small change like this:
result=eval(function.replace("x",str(x)))
This yet not the best way to do this you should use generator there:
def maxf(function,interval):
maxresult = 0
for x in range(interval[0]-1,interval[1]+1):
yield eval(function.replace("x",str(x))), x
print(max(maxf("x**2", [1, 3])))
A more pythonic approach would be using lambda with max function as a key
a_list = [1,3]
max_item = max(a_list, key=lambda x: eval("x**2"))
print(eval("x**2".replace("x", str(max_item))), max_item)

Problem with scipy.optimize.newton(): "Add" object is not callable

I'm writing a function that takes 2 lists and creates a polynomial function to later be solved by optimization.
I'm trying to create a string that looks like a function, convert it into a function by using sympy.sympify() and then pass it into optimize.newton().
However it keeps throwing a TypeError "Add" object is not callable while I already think that sympify has correctly returned a function.
I think I'm missing something very basic, maybe there is a function to turn my variable function0 into a function type for scipy to interpret correctly maybe?
def poly_build(coefficient_list, power_list):
'''
coefficient_list & power_list must be iterable objects of the same length, preferably a list
'''
if len (coefficient_list) != len(power_list):
return False
function = ""
for n in range(0, len(coefficient_list)):
if n != len(coefficient_list) - 1:
function += f'{coefficient_list[n]}*x**{power_list[n]} +'
else:
function += f'{coefficient_list[n]}*x**{power_list[n]}'
function0 = (sympy.sympify(function))
function1 = sympy.diff(function0)
function2 = sympy.diff(function1)
return scipy.optimize.newton(function0, 1.5)
A sympy function isn't a Python function as scipy.optimize.newton expects it. To convert:
pyfunction0 = sympy.lambdify(x, function0)

TypeError: float() argument must be a string or a number, not 'method'

I am trying to convert the latitude and longitude to zipcodes for around 10k data points. I am using geocoder for the task.
lat = subsamp['Latitude'].as_matrix
long = subsamp['Longitude'].as_matrix
g = geocoder.google([lat, long], method='reverse')
zip = g.postal
But, on executing the geocoder I get the error:
TypeError: float() argument must be a string or a number, not 'method'
I tried running it using a Pandas series then Numpy array but does not work.
Its a Missing parentheses issue for .as_matrix,
pandas.DataFrame.as_matrix, is a method
used to convert the frame to its Numpy-array representation.
As it is a function, you missed the (), you have not added () function parenthesis, for .as_matrix.
lat = subsamp['Latitude'].as_matrix
long = subsamp['Longitude'].as_matrix
It should be as follows :
lat = subsamp['Latitude'].as_matrix()
long = subsamp['Longitude'].as_matrix()
zip is a number or string but you have assigned a function to this value.
zip = g.postal -> zip = g.postal()

Mapping python tuple and R list with rpy2?

I'm having some trouble to understand the mapping with rpy2 object and python object.
I have a function(x) which return a tuple object in python, and i want to map this tuple object with R object list or vector.
First, i'm trying to do this :
# return a python tuple into this r object tlist
robjects.r.tlist = get_max_ticks(x)
#Convert list into dataframe
r('x <- as.data.frame(tlist,row.names=c("seed","ticks"))')
FAIL with error :
rinterface.RRuntimeError: Error in eval(expr, envir, enclos) : object 'tlist' not found
So i'm trying an other strategy :
robjects.r["tlist"] = get_max_ticks(x)
r('x <- as.data.frame(tlist,row.names=c("seed","ticks"))')
FAIL with this error :
TypeError: 'R' object does not support item assignment
Could you help me to understand ?
Thanks a lot !!
Use globalEnv:
import rpy2.robjects as ro
r=ro.r
def get_max_ticks():
return (1,2)
ro.globalEnv['tlist'] = ro.FloatVector(get_max_ticks())
r('x <- as.data.frame(tlist,row.names=c("seed","ticks"))')
print(r['x'])
# tlist
# seed 1
# ticks 2
It may be possible to access symbols in the R namespace with this type of notation: robjects.r.tlist, but you can not assign values this way. The way to assign symbol is to use robject.globalEnv.
Moreover, some symbols in R may contain a period, such as data.frame. You can not access such symbols in Python using notation similar to robjects.r.data.frame, since Python interprets the period differently than R. So I'd suggest avoiding this notation entirely, and instead use
robjects.r['data.frame'], since this notation works no matter what the symbol name is.
You could also avoid the assignment in R all together:
import rpy2.robjects as ro
tlist = ro.FloatVector((1,2))
keyWordArgs = {'row.names':ro.StrVector(("seed","ticks"))}
x = ro.r['as.data.frame'](tlist,**keyWordArgs)
ro.r['print'](x)

Categories

Resources