I am looking for some help with creating a code for the following in python
I have made an attempt at an answer but I am not quite sure how to finish it. Here is what I have so far
import numpy as np
import math
from numpy import cos
x=10**(-p)
funct = (1-math.cos(x))/x
So I have defined my function that I am trying to calculate, I believe I did that correctly with
funct = (1-math.cos(x))/x
I have said what x needs to be with
x=10**(-p)
But how do I add the code to find the smallest value of p which has no correct significant digit at x = 10**-p when using standard double precision?
Do I need to somehow use
print(min(funct))
Looking for some help with this execution, thanks!
Edit: new code
import numpy as np
import math
for p in range(10):
x=10.0**-p;
result = (1-np.cos(x))/x
print (p)
print (result)
Test = 2*np.sin(x/2)**2/x
print (p)
print(Test)
gives the results:
0
0.459697694132
0
0.459697694132
1
0.0499583472197
1
0.0499583472197
2
0.00499995833347
2
0.00499995833347
3
0.000499999958326
3
0.000499999958333
4
4.99999996961e-05
4
4.99999999583e-05
5
5.0000004137e-06
5
4.99999999996e-06
6
5.00044450291e-07
6
5e-07
7
4.99600361081e-08
7
5e-08
8
0.0
8
5e-09
9
0.0
9
5e-10
With the loop
for p in range(15): x=10.0**-p; print p, x, (1-np.cos(x))/x, 2*np.sin(x/2)**2/x
I get the values for the expression and a theoretically equivalent expression
p x (1-cos(x))/x 2*sinĀ²(x/2)/x
0 1.0 0.459697694132 0.459697694132
1 0.1 0.0499583472197 0.0499583472197
2 0.01 0.00499995833347 0.00499995833347
3 0.001 0.000499999958326 0.000499999958333
4 0.0001 4.99999996961e-05 4.99999999583e-05
5 1e-05 5.0000004137e-06 4.99999999996e-06
6 1e-06 5.00044450291e-07 5e-07
7 1e-07 4.99600361081e-08 5e-08
8 1e-08 0.0 5e-09
9 1e-09 0.0 5e-10
10 1e-10 0.0 5e-11
11 1e-11 0.0 5e-12
12 1e-12 0.0 5e-13
13 1e-13 0.0 5e-14
14 1e-14 0.0 5e-15
but I have no idea how to interpret the task to give a valid answer. Could be p=5 or could be p=8.
Related
I am using make_interp_spline to do curve fitting. I'd like to keep same values beyond min and max values. I thought I could using bc_type='clamped' to do that. But the result I got is not correct.
Here is what I have
the data is
df_krow
Sw Krw Krow
0 0.247000 0.000000 1.000000
1 0.281562 0.000006 0.850997
2 0.316125 0.000098 0.716177
3 0.350688 0.000494 0.595057
4 0.385250 0.001563 0.487139
5 0.419813 0.003815 0.391906
6 0.454375 0.007910 0.308816
7 0.488938 0.014655 0.237305
8 0.523500 0.025000 0.176777
9 0.558063 0.040045 0.126603
10 0.592625 0.061035 0.086115
11 0.627188 0.089362 0.054592
12 0.661750 0.126562 0.031250
13 0.696313 0.174323 0.015223
14 0.730875 0.234473 0.005524
15 0.765437 0.308990 0.000977
16 0.800000 0.400000 0.000000
sw_loc_list=[0.2,0.4,0.6,0.8,0.9,1.0]
from scipy.interpolate import make_interp_spline
krw_loc_list=make_interp_spline(df_krow['Sw'],df_krow['Krw'],k=3,bc_type='clamped')(sw_loc_list)
after above, you can see when sw<0.247 or higher than 0.8, Krw is negative. The result I'd like to get is Krw is 0 when Sw<0.247 and Krw=0.4 when Sw>0.8. How to do it? Thanks
print(krw_loc_list)
[-4.21675500e-05 2.34342851e-03 6.64037797e-02 4.00000000e-01
-2.73531731e+00 -1.91966201e+01]
DP 1 DP 2 DP 3 DP 4 DP 5 DP 6 DP 7 DP 8 DP 9 DP 10
OP 1 2.33 1.711 1.218 1.046 1.150 1.025 1.046 1.092 nan -
OP 2 3.043 1.691 1.362 1.174 1.067 1.048 1.051 1.059
OP 3 4.054 1.717 1.238 1.132 1.068 1.056 1.045
OP 4 3.014 1.748 1.327 1.103 1.093 1.116
OP 5 2.798 1.862 1.241 1.242 1.148
OP 6 3.973 1.589 1.553 1.161
OP 7 3.372 1.552 1.458
OP 8 3.359 1.871
OP 9 3.494
OP 10
this is the dataframe DF1 ;
for ele in DF1:
x = ele+2.0
print(x)
this will give the output:
DP 1 DP 2 DP 3 DP 4 DP 5 DP 6 DP 7 DP 8 DP 9 DP 10
OP 1 4.33 3.711 3.218 3.046 3.150 3.025 3.046 3.092 nan -
OP 2 5.043 3.691 3.362 3.174 3.067 3.048 3.051 3.059
OP 3 6.054 3.717 3.238 3.132 3.068 3.056 3.045
OP 4 5.014 3.748 3.327 3.103 3.093 3.116
OP 5 4.798 3.862 3.241 3.242 3.148
OP 6 5.973 3.589 3.553 3.161
OP 7 5.372 3.552 3.458
OP 8 5.359 3.871
OP 9 5.494
OP 10
But i Need Output like :
DP 1 DP 2 DP 3 DP 4 DP 5 DP 6 DP 7 DP 8 DP 9 DP 10
OP 1 4.33 3.711 3.218 3.046 3.150 3.025 3.046 3.092 2.0 -
OP 2 5.043 3.691 3.362 3.174 3.067 3.048 3.051 3.059
OP 3 6.054 3.717 3.238 3.132 3.068 3.056 3.045
OP 4 5.014 3.748 3.327 3.103 3.093 3.116
OP 5 4.798 3.862 3.241 3.242 3.148
OP 6 5.973 3.589 3.553 3.161
OP 7 5.372 3.552 3.458
OP 8 5.359 3.871
OP 9 5.494
OP 10
that means if i add nan to number then it should give the respective number.
Does this help?
for ele in DF1:
for ind,val in ele:
if np.isnan(val):
ele[ind] = 2.0
else:
ele[ind] = val+2.0
As you want:
import pandas as pd
import numpy as np
data = [[1,10],[2,12],[3,13],[4,10],[5,12],[np.nan,13]]
df = pd.DataFrame(data,columns=['a','b'],dtype=float)
for element in df['a']:
if(element >= 0):
x = element + 2.0
else:
x = 2.0
print(x)
Easy Way:
df.fillna(2.0)
One way is to simply redefine addition so that x+nan evaluates to x, but that's rather dangerous. Safer is to define a custom function:
def nan_sum(a,b):
if not a:
return b
if not b:
return a
return a+b
Then you can apply it to the dataframe: DF1.applymap(lambda x: nan_sum(x,2.0))
You can utilize the np.nan_to_num() function which is specifically designed to replace nans with zeros. Its default behavior is to replace nans with 0.0.
import numpy as np
df.applymap(lambda x: np.nan_to_num(x)+2)
This question already has answers here:
Pandas Merging 101
(8 answers)
Closed 2 years ago.
I started to work with pandas very recently, and my issue is the following: I have two loops, that generates each 10 values. What I want to do is to insert at the bottom of my data frame the generated values, in such a way that the index is the same for both loops.
Here is a mock-up example, that is quite close of what I'm trying to do:
import pandas as pd
import random
randint = {'rand': [10,52,99,8],'rand2': [541,632,789,251], 'rand3': [1,3,4,1]}
df = pd.DataFrame(randint, columns = ['rand','rand2', "rand3"])
i = j = len(df)
for x in range(10):
rand = random.randint(1,101)
rand2 = random.randint(1,1001)
df.loc[df.index[i], "rand"] = rand
df.loc[df.index[i], "rand2"] = rand2
i = i + 1
for y in range(10):
rand3 = random.randint(1,11)
df.loc[df.index[j], "rand3"] = rand3
j = j + 1
print(df)
So, what I would like is to have for instance at row 5 the first set of rand, rand2, rand3 at the same row, and so forth (e.g.: for x and y = 1, I would have the three values at the same row, for x and y = 2, same thing, etc...). The issue is that I have read that it was not a good idea to iterate with pandas (and obviously, pandas is raising me the error "index 4 is out of bounds for axis 0 with size 4"), but I really have trouble to understand the pandas syntax and I'm a bit lost on how I am supposed to tackle this issue. Thank you for your help.
Expected output:
At first, my dataframe would look like this:
rand
rand2
rand3
10
541
1
52
632
3
99
789
4
8
251
1
Now, let us imagine that the first time in the first loop (so for x = 1) , rand = 8, rand2 = 455, and for the first time of the second loop (so for y=1), rand3 = 7.
So now, I would like to add the values obtained to the last row, in such a way that my dataframe would look like this:
rand
rand2
rand3
10
541
1
52
632
3
99
789
4
8
251
1
8
455
7
The issue is that I don't really know to indicate to pandas that I want to have the same index for the two loops. Let me know if it is still not clear.
I am not sure if this is the case, but in your example the second loop is working on rand2 column and not rand3. Also, when you use df.loc use the value of i or j (not df.index[i/j])
i = j = len(df)
for x in range(10):
rand = random.randint(1,101)
rand2 = random.randint(1,1001)
df.loc[i, "rand"] = rand
df.loc[i, "rand2"] = rand2
i = i + 1
for y in range(10):
rand3 = random.randint(1,11)
df.loc[j, "rand3"] = rand3
j = j + 1
print(df)
rand rand2 rand3
0 10.0 541.0 1.0
1 52.0 632.0 3.0
2 99.0 789.0 4.0
3 8.0 251.0 1.0
4 37.0 902.0 6.0
5 65.0 717.0 11.0
6 95.0 345.0 6.0
7 81.0 218.0 9.0
8 90.0 233.0 10.0
9 15.0 918.0 6.0
10 62.0 775.0 10.0
11 27.0 955.0 4.0
12 43.0 17.0 2.0
13 69.0 41.0 8.0
Pandas way of doing this is like that:
>>> import numpy as np
>>> pd.DataFrame({
'rand': np.random.randint(1,101,10),
'rand2': np.random.randint(1,1001,10),
'rand3': np.random.randint(1,11,10)})
rand rand2 rand3
0 50 877 5
1 9 929 5
2 23 605 7
3 52 205 4
4 39 341 6
5 17 455 7
6 11 505 7
7 68 647 10
8 66 920 6
9 63 386 9
I use python pandas to caculate the following formula
(https://i.stack.imgur.com/XIKBz.png)
I do it in python like this :
EURUSD['SMA2']= EURUSD['Close']. rolling (2).mean()
EURUSD['TMA2']= ( EURUSD['Close'] + EURUSD[SMA2']) / 2
The proplem is long coding when i calculated TMA 100 , so i need to use " for loop " to easy change TMA period .
Thanks in advance
Edited :
I had found the code but there is an error :
values = []
for i in range(1,201): values.append(eurusd['Close']).rolling(window=i).mean() values.mean()
TMA is average of averages.
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 5))
print(df)
# df['mean0']=df.mean(0)
df['mean1']=df.mean(1)
print(df)
df['TMA'] = df['mean1'].rolling(window=10,center=False).mean()
print(df)
Or you can easily print it.
print(df["mean1"].mean())
Here is how it looks:
0 1 2 3 4
0 0.643560 0.412046 0.072525 0.618968 0.080146
1 0.018226 0.222212 0.077592 0.125714 0.595707
2 0.652139 0.907341 0.581802 0.021503 0.849562
3 0.129509 0.315618 0.711265 0.812318 0.757575
4 0.881567 0.455848 0.470282 0.367477 0.326812
5 0.102455 0.156075 0.272582 0.719158 0.266293
6 0.412049 0.527936 0.054381 0.587994 0.442144
7 0.063904 0.635857 0.244050 0.002459 0.423960
8 0.446264 0.116646 0.990394 0.678823 0.027085
9 0.951547 0.947705 0.080846 0.848772 0.699036
0 1 2 3 4 mean1
0 0.643560 0.412046 0.072525 0.618968 0.080146 0.365449
1 0.018226 0.222212 0.077592 0.125714 0.595707 0.207890
2 0.652139 0.907341 0.581802 0.021503 0.849562 0.602470
3 0.129509 0.315618 0.711265 0.812318 0.757575 0.545257
4 0.881567 0.455848 0.470282 0.367477 0.326812 0.500397
5 0.102455 0.156075 0.272582 0.719158 0.266293 0.303313
6 0.412049 0.527936 0.054381 0.587994 0.442144 0.404901
7 0.063904 0.635857 0.244050 0.002459 0.423960 0.274046
8 0.446264 0.116646 0.990394 0.678823 0.027085 0.451842
9 0.951547 0.947705 0.080846 0.848772 0.699036 0.705581
0 1 2 3 4 mean1 TMA
0 0.643560 0.412046 0.072525 0.618968 0.080146 0.365449 NaN
1 0.018226 0.222212 0.077592 0.125714 0.595707 0.207890 NaN
2 0.652139 0.907341 0.581802 0.021503 0.849562 0.602470 NaN
3 0.129509 0.315618 0.711265 0.812318 0.757575 0.545257 NaN
4 0.881567 0.455848 0.470282 0.367477 0.326812 0.500397 NaN
5 0.102455 0.156075 0.272582 0.719158 0.266293 0.303313 NaN
6 0.412049 0.527936 0.054381 0.587994 0.442144 0.404901 NaN
7 0.063904 0.635857 0.244050 0.002459 0.423960 0.274046 NaN
8 0.446264 0.116646 0.990394 0.678823 0.027085 0.451842 NaN
9 0.951547 0.947705 0.080846 0.848772 0.699036 0.705581 0.436115
I've been working on this all morning and for the life of me cannot figure it out. I'm sure this is very basic, but I've become so frustrated my mind is being clouded. I'm attempting to calculate the total return of a portfolio of securities at each date (monthly).
The formula is (1 + r1) * (1+r2) * (1+ r(t))..... - 1
Here is what I'm working with:
Adj_Returns = Adj_Close/Adj_Close.shift(1)-1
Adj_Returns['Risk Parity Portfolio'] = (Adj_Returns.loc['2003-01-31':]*Weights.shift(1)).sum(axis = 1)
Adj_Returns
SPY IYR LQD Risk Parity Portfolio
Date
2002-12-31 NaN NaN NaN 0.000000
2003-01-31 -0.019802 -0.014723 0.000774 -0.006840
2003-02-28 -0.013479 0.019342 0.015533 0.011701
2003-03-31 -0.001885 0.010015 0.001564 0.003556
2003-04-30 0.088985 0.045647 0.020696 0.036997
For example, with 2002-12-31 being base 100 for risk parity, I want 2003-01-31 to be 99.316 (100 * (1-0.006840)), 2003-02-28 to be 100.478 (99.316 * (1+ 0.011701)) so on and so forth.
Thanks!!
You want to use pd.DataFrame.cumprod
df.add(1).cumprod().sub(1).sum(1)
Consider the dataframe of returns df
np.random.seed([3,1415])
df = pd.DataFrame(np.random.normal(.025, .03, (10, 5)), columns=list('ABCDE'))
df
A B C D E
0 -0.038892 -0.013054 -0.034115 -0.042772 0.014521
1 0.024191 0.034487 0.035463 0.046461 0.048123
2 0.006754 0.035572 0.014424 0.012524 -0.002347
3 0.020724 0.047405 -0.020125 0.043341 0.037007
4 -0.003783 0.069827 0.014605 -0.019147 0.056897
5 0.056890 0.042756 0.033886 0.001758 0.049944
6 0.069609 0.032687 -0.001997 0.036253 0.009415
7 0.026503 0.053499 -0.006013 0.053447 0.047013
8 0.062084 0.029664 -0.015238 0.029886 0.062748
9 0.048341 0.065248 -0.024081 0.019139 0.028955
We can see the cumulative return or total return is
df.add(1).cumprod().sub(1)
A B C D E
0 -0.038892 -0.013054 -0.034115 -0.042772 0.014521
1 -0.015641 0.020983 0.000139 0.001702 0.063343
2 -0.008993 0.057301 0.014565 0.014247 0.060847
3 0.011544 0.107423 -0.005853 0.058206 0.100105
4 0.007717 0.184750 0.008666 0.037944 0.162699
5 0.065046 0.235405 0.042847 0.039769 0.220768
6 0.139183 0.275786 0.040764 0.077464 0.232261
7 0.169375 0.344039 0.034505 0.135051 0.290194
8 0.241974 0.383909 0.018742 0.168973 0.371151
9 0.302013 0.474207 -0.005791 0.191346 0.410852
Plot it
df.add(1).cumprod().sub(1).plot()
Add sum of returns to new column
df.assign(Portfolio=df.add(1).cumprod().sub(1).sum(1))
A B C D E Portfolio
0 -0.038892 -0.013054 -0.034115 -0.042772 0.014521 -0.114311
1 0.024191 0.034487 0.035463 0.046461 0.048123 0.070526
2 0.006754 0.035572 0.014424 0.012524 -0.002347 0.137967
3 0.020724 0.047405 -0.020125 0.043341 0.037007 0.271425
4 -0.003783 0.069827 0.014605 -0.019147 0.056897 0.401777
5 0.056890 0.042756 0.033886 0.001758 0.049944 0.603835
6 0.069609 0.032687 -0.001997 0.036253 0.009415 0.765459
7 0.026503 0.053499 -0.006013 0.053447 0.047013 0.973165
8 0.062084 0.029664 -0.015238 0.029886 0.062748 1.184749
9 0.048341 0.065248 -0.024081 0.019139 0.028955 1.372626