Coding problems when define something, but can't plot them - python

import numpy as N
from matplotlib import pylab as plt
def function2(t):
if (t-N.floor(t))<0.5:
return -1
else:
return 1
def function3(t):
if t<=5:
return N.cos(40*N.pi*t)
else:
return 0
x2= N.linspace(0,10,1024)
y2= function2(x2)
x3= N.linspace(0,40,8192)
y3= function3(x3)
plt.plot(x2,y2)
plt.show()
No matter I try plot(x2,y2) or (x3,y3), it shows error message, but I can print any single value of function2 and function3 without any problems.
I'm stuck here. Thanks in advance.

You are having:
Traceback (most recent call last):
File "b.py", line 16, in <module>
y2= function2(x2)
File "b.py", line 4, in function2
if (t-N.floor(t))<0.5:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
which comes from the line:
if (t-N.floor(t))<0.5:
Here you are doing if array < 0.5. What is your intent?
If you want to check all elements of the array > 0.5, you can:
all(array < 0.5)

function2 and function3 is a scalar function. You need to convert them into vectorized one:
x2 = N.linspace(0,10,1024)
y2 = N.vectorize(function2)(x2)
x3 = N.linspace(0,40,8192)
y3 = N.vectorize(function3)(x3)
See numpy.vectorize.

What you were doing, was applying array comparison, which gives you an array of True/False. So your if function evaluates to both at the same time. That raises an error.
While the solution proposed #falsetru is acceptable, I strongly advise against using vectorize, since it adds unnecessary for loops. Instead you can utilize the strength of numpy to do simple comparison operations above. Example: if a is an array (a>0) returns an element-wise boolean array with True(1) or False(0), which later can be operated on. Your code should look like this:
def function2(t):
return 1-2*(t-N.floor(t)<0.5) # returns 1- 2*True(1)/False(0)
def function3(t):
return (t<=5)*N.cos(40*pi*t) # returns 0 if t<=5 evaluates to False
x2= N.linspace(0,10,1024)
y2= function2(x2)
x3= np.linspace(0,40,8192)
y3= function3(x3)
plt.plot(x2,y2)
ylim(-2,2)
plt.show()

Related

How to perform Mann-Whitney U test in python with cycle?

I have a loop that gives new values k1 and k2 each time, but the problem is that in my dataset there are cases where all values are zero in both k1 and k2. When the program comes to them, it just throws an error and does not complete the loop, and there is still a lot of calculations. How can I make such cases just be signed, like NA or something else, and the cycle goes on?
python3
import pandas
from scipy.stats import mannwhitneyu
print(mannwhitneyu(k1, k2))
I conduct this Mann-Whitney U test for different observations and I want the cycle not to stop at an error, but simply to note that it is impossible here
Error example(line 3, above are normal):
MannwhitneyuResult(statistic=3240.0, pvalue=0.16166098643677973)
MannwhitneyuResult(statistic=2958.5, pvalue=0.008850960706454409)
Traceback (most recent call last):
File "ars1", line 95, in <module>
print(mannwhitneyu(k1, k2))
File "/storage/software/python-3.6.0/lib/python3.6/site-packages/scipy/stats/stats.py", line 4883, in mannwhitneyu
raise ValueError('All numbers are identical in mannwhitneyu')
ValueError: All numbers are identical in mannwhitneyu
You can continue with loop if 2 arrays are equal. For instance, if:
k1 = [0,0,0,0,0];
k2 = [0,0,0,0,0];
then you can check whether k1 == k2. If it is true, just use continue for your loop. Like this:
if ( k1 == k2 ) == True: continue
just before you call mannwhitneyu(k1, k2)
I tried it in loop and also saved it in csv file in a folder
convert your series in the list and check for the equality it will work
for y in df.columns:
target = df[y]
list_mann_white = []
for x in df.columns:
if list(target) == list(df[x]):
pass
else:
list_mann_white.append([stats.mannwhitneyu(target,df[x])[1],x])
list_mann_white.sort()
mann_csv = pd.DataFrame(chi_list)
mann_csv.to_csv('Mann/target_{}.csv'.format(y))

Python Numpy Exponential Value from Array of BigFloats

I'm trying to compute the natural log of the exponential plus the median of an array but precision of the floating point numbers has to be at 2000 or the answer will always be 0.
Here is what I have so far:
import bigfloat
x = np.array([-15349.79, -15266.66, -15242.86])
answer = np.median(x) - bigfloat.log(np.mean(bigfloat.exp(x, precision(2000)) + np.median(x)))
This code returns the following error because BigFloat.exp doesn't work on list types.
__main__:1: RuntimeWarning: invalid value encountered in log
array([ nan, nan, nan])
>>> np.median - bigfloat.log(np.mean(bigfloat.exp(x, precision(2000)) + np.median(x)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/bigfloat/core.py", line 1446, in exp
(BigFloat._implicit_convert(x),),
File "/usr/local/lib/python2.7/dist-packages/bigfloat/core.py", line 800, in _implicit_convert
"to BigFloat" % (arg, type(arg)))
TypeError: Unable to convert argument [-15349.79 -15266.66 -15242.86] of type <type 'numpy.ndarray'> to BigFloat
I then tried list comprehension to build exponentials with precision=2000 but the output loses precision.
>>>[bigfloat.exp(num, precision(2000)) + BigFloat(np.median(x), context=precision(2000)) for num in x]
[BigFloat.exact('-15266.660000000000', precision=53), BigFloat.exact('-15266.660000000000', precision=53), BigFloat.exact('-15266.660000000000', precision=53)]
I can get exponential values from x with precision using list comprehension
like this:
>>> y = np.array([bigfloat.exp(num, precision(2000)) for num in x])
array([ BigFloat.exact('4.687104391719151845495683439738733373338442839115295629901427982078731632624437676931490944129698360820181432182432247030174990996132679553420878801399467284014932435857939862423137788809352433385343338286781879066456873472082636971652587852379587642184738259777920214145750081457830886095059600271300801524086458081526778407096875577469007859748418787409261916565428551066536598870494431653463691369520685259389041691328858076222360659135651318185915247243253437425313718584237418827954902711646850362440592578566737383074556346759332830833101196990845567845361685702120838400980658468192376607029699380e-6667', precision=2000),
BigFloat.exact('5.940252515613784074556309936460240719247289162721506036367173706446251980105141516508485353816420203092949808160441872102510858074752258842471232457791645630942356791030979819957875784926363292788234347364203226596687259399429746917920741954706671428927952815041593801046941161417184730521922391569252658359604561007344640221209247257690437938341582528542446104212627600044421405229891732857592357725820529732658234033631318425476205945557122313924830225909708184718714804450362854280687393958953216361511561704836206669636791590655443171684811683402330053964681285971765503804198242627954802184910024902e-6631', precision=2000),
BigFloat.exact('1.288289823457680769007768910906908351089465066737359292851136781233384628626343352992636825492031571595103435334370758196286825224816434202324210124540257467624499933926757723584914581286627071375803686797647455160335628799775858142489656885909172399293492295645703203222218182084249732700966821340431452575815746282651823925677898549539269454644804048695031225101971491985645951419388454738446335860070391719831039721150295437452237572831818257568221336263814212095143032293694959570063677473370798577031762607527221992020661837810811705007892502559603984057933079724597470162879821292957122400421187875e-6620', precision=2000)], dtype=object)
So, how do I add np.median(x) to each item in the exponential array and how do I get the log of the elements in the final array? Is there an easier way to compute the equation given by variable answer in the first code snippet above?
I'm basically trying to convert this R code to Python:
llMed <- stats::median(x)
metric <- as.double(
llMed - log( Rmpfr::mean( exp( -Rmpfr::mpfr(x, prec=2000L) + llMed )))
)
I think I was able to transpose the R code above, using gmpy2 instead of BigFloat but probably could have used either:
import gmpy2 as gp
import numpy as np
with gp.local_context(gp.context(), precision=2000) as ctx:
x = np.array([gp.mpfr(-15349.79), gp.mpfr(-15266.66), gp.mpfr(-15242.86)])
answer = np.median(x) - gp.log(np.mean([gp.exp(gp.add(np.median(x), -gp.mpfr(item))) for item in x]))
Output returns:
mpfr('-15348.69138771133276342351845677418587273364155071266454924792376077085597654860712492594599688058199377288639137666410888137048513058096745776113277020531535761588878042016412651412489608285582998650481415959482636259292554205272401992800167437149224493900214813760731711328834885525224938584036572786202764947113186177391441168267495103157033223800214492991771147327262071249020907408433551462034872024117419365924381891832161483692689444158313503155805562703358104122358438183824459422779020196496507161021965435781332319270106503099589290788685588200038739438059696970511568363022088057740627040541967',2000)

receiving "ValueError: setting an array element with a sequence."

I've been having some problems with this code, trying to end up with an inner product of two 1-D arrays. The code of interest looks like this:
def find_percents(i):
percents=[]
median=1.5/(6+2*int(i/12))
b=2*median
m=b/(7+2*int(i/12))
for j in xrange (1,6+2*int(i/12)):
percents.append(float((b-m*j)))
percentlist=numpy.asarray(percents, dtype=float)
#print percentlist
total=sum(percentlist)
return total, percentlist
def playerlister(i):
players=[]
for i in xrange(i+1,i+6+2*int(i/12)):
position=sheet.cell(i,2)
points=sheet.cell(i,24)
if re.findall('RB', str(position.value)):
vbd=points.value-rbs[24]
players.append(vbd)
else:
pass
playerlist=numpy.asarray(players, dtype=float)
return playerlist
def others(i,percentlist,playerlist,total):
alternatives=[]
playerlist=playerlister(i)
percentlist=find_percents(i)
players=numpy.dot(playerlist,percentlist)
I am receiving the following error in response to the very last line of this attached code:
ValueError: setting an array element with a sequence.
In most other examples of this error, I have found the error to be because of incorrect data types in the arrays percentlist and playerlist, but mine should be float type. If it helps at all, I call these functions a little later in the program, like so:
for i in xrange(1,30):
total, percentlist= find_percents(i)
playerlist= playerlister(i)
print type(playerlist[i])
draft_score= others(i,percentlist,playerlist,total)
Can anyone help me figure out why I am setting an array element with a sequence? Please let me know if any more information might be helpful! Also for clarity, the playerlister is making use of the xlrd module to extract data from a spreadsheet, but the data are numerical and testing has shown that that both lists have a type of numpy.float64.
The shape and contents of each of these for one iteration of i is
<type 'numpy.float64'>
(5,)
[ 73.7 -94.4 140.9 44.8 130.9]
(5,)
[ 0.42857143 0.35714286 0.28571429 0.21428571 0.14285714]
Your function find_percents returns a two-element tuple.
When you call it in others, you are binding that tuple to the variable named percentlist, which you then try to use in a dot-product.
My guess is that by writing this in others it is fixed:
def others(i,percentlist,playerlist,total):
playerlist = playerlister(i)
_, percentlist = find_percents(i)
players = numpy.dot(playerlist,percentlist)
provided of course playerlist and percentlist always have the same number of elements (which we can't check because of the missing spreadsheet).
To verify, the following gives you the exact error message and the minimum of code needed to reproduce it:
>>> import numpy as np
>>> a = np.arange(5)
>>> np.dot(a, (2, a))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: setting an array element with a sequence.

writing a function with input of array...'int' object has no attribute '__getitem__'

I'm a beginner in python. I wrote a function as follows:
import numpy as np
def crossover(v1,v2):
N=2
v1n=np.zeros(shape=(1,N+1))
v2n=np.zeros(shape=(1,N+1))
beta=np.random.rand(1)
v1n[0,0]=(1-beta)*v1[0]+beta*v2[0]
v1n[0][1]=v1[1]
v2n[0][0]=(1-beta)*v2[0]+beta*v1[0]
v2n[0][1]=v2[1]
return (v1n,v2n)
when I want to see crossover([3,4],[7,8]), the following error....:
Traceback (most recent call last):
File "<pyshell#82>", line 1, in <module>
crossover([4,5],[5,4])
File "C:\Python27\crossover.py", line 11, in crossover
v1n[0,0]=(1-beta)*v1[0]+beta*v2[0]
TypeError: 'int' object has no attribute '__getitem__'
Your code is running fine on python 2.7.8 (on my computer). But i suggest your output is bad.
if you run your code you get output:
(array([[ 4.91965332, 5. , 0. ]]), array([[ 4.08034668, 4. , 0. ]]))
This is actually a tuple with two arrays containing each a list.
you are using numpy for small 'arrays' and that is actually slower than normal list.
numpy is used for hundreds, even thousands of data.
check this link for more info about numpy speed
i would suggest you just use list instead.
let me give you an example on how i would have done it without numpy :D
import random
v1=[5,4]
v2=[4,5]
# basicly random number from 0 to 1
beta=random.random()
# let's initialize v1n and v2n (:
v1n = [0,0,0]
v2n = [0,0,0]
v1n[0] = (1-beta)*v1[0]+beta*v2[0]
v1n[1] = v1[1]
v2n[0] = (1-beta)*v2[0]+beta*v1[0]
v2n[1]=v2[1]
print("first 3d array:")
print(v1n)
print("second 3d array:")
print(v2n)
print("note that this really is 2d arrays because the 3rd dimension is always zero")

quadpack.error: Supplied function does not return a valid float in python

I would like to integrate a function with respect to (z) and make (x) and (y) as arguments. My goal is to get the result of integration at different location (x,y), In this case, I should get 16 values of integration which correspond to (x1,y1), (x1,y2) ..., (x2,y1) ... and so on.
This is the code:
import numpy as np
import math
import scipy.integrate
a = 5
b = 6
xn=np.linspace(0,3,4)
yn=np.linspace(3,6,4)
x,y=np.ix_(xn,yn)
def fun(z,x,y):
model=(x**2/a**2+y**2/b**2+z**2/a**2)**0.5
#print(model)
return model
def int(x,y):
int=scipy.integrate.quad(fun,0,10,args=(x,y,))[0]
print (int)
return int
integral = int(x,y)
print (integral)
But I got this error message:
....
int=scipy.integrate.quad(model,0,10,args=(x,y,))[0]
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-
packages/scipy/integrate/quadpack.py", line 254, in quad
retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-
packages/scipy/integrate/quadpack.py", line 319, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
quadpack.error: Supplied function does not return a valid float.
Please could anyone show me how to fix this error and thank you in advance.
As the error suggests, your fun function should be returning a float but is instead returning a 2D array:
[[ 1.11803399 1.20185043 1.30170828 1.41421356]
[ 1.13578167 1.21837779 1.31698308 1.42828569]
[ 1.18743421 1.26666667 1.36177988 1.46969385]
[ 1.26885775 1.34329611 1.43333333 1.53622915]]
The function that you are integrating should evaluate to a single number at some point in parameter space.
If you are trying to do an N dimensional integral, you may want to look at scipy.integrate.nquad.

Categories