How to count number of peaks in graph ? -graph analysis- - excel

I have this curve that contains certain peaks - I want to know how to get the number of these peaks.
Sample Data:
0.10 76792
0.15 35578
0.20 44675
0.25 52723
0.30 27099
0.35 113931
0.40 111043
0.45 34312
0.50 101947
0.55 100824
0.60 20546
0.65 114430
0.70 113764
0.75 15713
0.80 83133
0.85 79754
0.90 17420
0.95 121094
1.00 117346
1.05 22841
1.10 95095
1.15 94999
1.20 18986
1.25 111226
1.30 106640
1.35 34781
1.40 66356
1.45 68706
1.50 21247
1.55 117604
1.60 114268
1.65 26292
1.70 88486
1.75 89841
1.80 49863
1.85 111938
The 1st column is the X values, the 2nd column is the y values.
I want to write a macro or formula that tell me how many peaks in this graph.
Note: this graph is actualy ploted and exported from matlab, so if there is a way i can tell my code to do it for me from matlab it would be also great!

if your data was in A1:B36 then this formula
=SUMPRODUCT(--(B2:B35>B1:B34),--(B2:B35>B3:B36))
returns 11 peaks
It checks if
B2 is higher than B1 and B3, if so counts it as a peak
then if B3 is higher than B2 and B4, if so counts it as a peak and so on
[Updated: VBA request added]
Sub GetMax()
Dim chr As ChartObject
Dim chrSeries As Series
Dim lngrow As Long
On Error Resume Next
Set chr = ActiveSheet.ChartObjects(1)
Set chrSeries = chr.Chart.SeriesCollection(1)
On Error GoTo 0
If chrSeries Is Nothing Then Exit Sub
For lngrow = 2 To UBound(chrSeries.Values) - 1
If chrSeries.Values(lngrow) > chrSeries.Values(lngrow - 1) Then
If chrSeries.Values(lngrow) > chrSeries.Values(lngrow + 1) Then
chrSeries.Points(lngrow).ApplyDataLabels
With chrSeries.Points(lngrow).DataLabel
.Position = xlLabelPositionCenter
.Border.Color = 1
End With
End If
End If
Next
End Sub

Related

Creating a new column into a dataframe based on conditions

For the dataframe df :
dummy_data1 = {'category': ['White', 'Black', 'Hispanic','White'],
'Pop':['75','85','90','100'],'White_ratio':[0.6,0.4,0.7,0.35],'Black_ratio':[0.3,0.2,0.1,0.45], 'Hispanic_ratio':[0.1,0.4,0.2,0.20] }
df = pd.DataFrame(dummy_data1, columns = ['category', 'Pop','White_ratio', 'Black_ratio', 'Hispanic_ratio'])
I want to add a new column to this data frame,'pop_n', by first checking the category, and then multiplying the value in 'Pop' by the corresponding ratio value in the columns. For the first row,
the category is 'White' so it should multiply 75 with 0.60 and put 45 in pop_n column.
I thought about writing something like :
df['pop_n']= (df['Pop']*df['White_ratio']).where(df['category']=='W')
this works but just for one category.
I will appreciate any helps with this.
Thanks.
Using DataFrame.filter and DataFrame.lookup:
First we use filter to get the columns with ratio in the name. Then split and keep the first word before the underscore only.
Finally we use lookup to match the category values to these columns.
# df['Pop'] = df['Pop'].astype(int)
df2 = df.filter(like='ratio').rename(columns=lambda x: x.split('_')[0])
df['pop_n'] = df2.lookup(df.index, df['category']) * df['Pop']
category Pop White_ratio Black_ratio Hispanic_ratio pop_n
0 White 75 0.60 0.30 0.1 45.0
1 Black 85 0.40 0.20 0.4 17.0
2 Hispanic 90 0.70 0.10 0.2 18.0
3 White 100 0.35 0.45 0.2 35.0
Locate the columns that have underscores in their names:
to_rename = {x: x.split("_")[0] for x in df if "_" in x}
Find the matching factors:
stack = df.rename(columns=to_rename)\
.set_index('category').stack()
factors = stack[map(lambda x: x[0]==x[1], stack.index)]\
.reset_index(drop=True)
Multiply the original data by the factors:
df['pop_n'] = df['Pop'].astype(int) * factors
# category Pop White_ratio Black_ratio Hispanic_ratio pop_n
#0 White 75 0.60 0.30 0.1 45
#1 Black 85 0.40 0.20 0.4 17
#2 Hispanic 90 0.70 0.10 0.2 18
#3 White 100 0.35 0.45 0.2 35

Excel and selecting variables conditionally

I have a data set which contains information by country. For example, Australia_F is the observation for Australia and Australia_Weight is the weight of Australia. Each period, represents a specific year.
Period Australia_F Canada_F Denmark_F Japan_F Australia_Weight Canada_Weight Denmark_Weight Japan_weight
1985 0.05 -0.02 0.02 0.03 0.10 0.30 0.45 0.15
1986 -0.04 -0.03 0.02 0.01 0.15 0.30 0.30 0.25
The user can input any value to the following cell. For example I have inserted 3
Weight_Modification = 3
The goal is to only include countries where the variable XXXXX_F are positive
and use those with the highest values such that the total weight of counties selected is not greater than 1.
The problem is complicated by the fact that the weight_modification variable, multiplies each individual county weight by whatever the value is. For example, the Weight for Australia would be 0.10 *3 = 0.3 in 1985.
Total weights can be less than 1.00 but can't be greater than 1.00
So taking the above data as an example and for 1985 the results would be
Australia_weight Canada_weight Denmark_weight Japan_weight Total_weight
0.3 0.45 0.75
This is because in 1985 Australia has the highest value (Australia_F = 0.05), followed by Japan (Japan_F = 0.03).
Each countries weights are multiplied by 3.
Denmark is not selected even through Denmark_F is positive, because including Denmark the total weight exceeds 1.
In the actual file there are many more countries (12 in total) and many years.
Any help with how to put this together in excel is greatly appreciated.

pandas, how to get close price from returns?

I'm trying to convert from returns to a price index to simulate close prices for the ffn library, but without success.
import pandas as pd
times = pd.to_datetime(pd.Series(['2014-07-4',
'2014-07-15','2014-08-25','2014-08-25','2014-09-10','2014-09-15']))
strategypercentage = [0.01, 0.02, -0.03, 0.04,0.5,-0.3]
df = pd.DataFrame({'llt_return': strategypercentage}, index=times)
df['llt_close']=1
df['llt_close']=df['llt_close'].shift(1)*(1+df['llt_return'])
df.head(10)
llt_return llt_close
2014-07-04 0.01 NaN
2014-07-15 0.02 1.02
2014-08-25 -0.03 0.97
2014-08-25 0.04 1.04
2014-09-10 0.50 1.50
2014-09-15 -0.30 0.70
How can I make this correct?
You can use the cumulative product of return-relatives.
A return-relative is one-plus that day's return.
>>> start = 1.0
>>> df['llt_close'] = start * (1 + df['llt_return']).cumprod()
>>> df
llt_return llt_close
2014-07-04 0.01 1.0100
2014-07-15 0.02 1.0302
2014-08-25 -0.03 0.9993
2014-08-25 0.04 1.0393
2014-09-10 0.50 1.5589
2014-09-15 -0.30 1.0912
This assumes the price index starts at start on the close of the trading day prior to 2014-07-04.
On 7-04, you have a 1% return and the price index closes at 1 * (1 + .01) = 1.01.
On 7-15, return was 2%; close price will be 1.01 * (1 + .02) = 1.0302.
Granted, this is not completely realistic given you're forming a price indexing from irregular-frequency data (missing dates), but hopefully this answers your question.

MCNP multiple cell sources with a lattice

I've been trying for a while to get a lattice-cell-source running with an ordinary cell-source in MCNP. I can get them both working separately but when I try and combine them I get the following fatal error: distribution 1 for cel is the wrong kind
My source code is as follows:
SDEF PAR=SF
CEL=D9 $ Fatal error. distribution 1 for cel is the wrong kind
X D11
Y D12
Z D13
c
DS9 S 4 10
DS11 S 1 14
DS12 S 2 15
DS13 S 3 16
c
c ---- Lattice cell source-----
SI4 L (3<2[-5:5 -5:5 -10:10]<5)
SP4 1 2540r
SI1 -0.12 0.12
SP1 0 1
SI2 -0.12 0.12
SP2 0 1
SI3 -0.12 0.12
SP3 0 1
c
c ---- Separate cell source ---
SI10 L 25
SP10 1
SI14 22.8 27.2
SP14 0 1
SI15 -2.2 2.2
SP15 0 1
SI16 -2.2 2.2
SP16 0 1
Do any of you know how to declare an embedded source along with an ordinary cell source? Image of the lattice and cell source: light blue indicates source material:
Any help much appreciated.
With help from a colleague we have found a solution, included below. It involves including an FCEL dependency on each distribution, as well as calling the cells directly within the CEL distribution without adding another D-card. Then ALL of the cells must be included in the following distributions.
SDEF PAR=SF
CEL=D9
X=FCEL D11
Y=FCEL D12
Z=FCEL D13
c
c
SI9 L (3<2[-5:5 -5:5 -10:10]<5) 25
c Cells 3 and 25 are called (3 is in the lattice notation)
SP9 1 2540r 2079
c assigning importance to each cell: lattice ~55%, PuO ball ~45%
DS11 S 1 2540r 14
c First 2541 cells have D1 attached, the last cell is attached to D14
DS12 S 2 2540r 15
c First 2541 cells have D2 attached, the last cell is attached to D15
DS13 S 3 2540r 16
c First 2541 cells have D3 attached, the last cell is attached to D16
c
c ---- Lattice cell source-----
SI1 -0.12 0.12
SP1 0 1
SI2 -0.12 0.12
SP2 0 1
SI3 -0.12 0.12
SP3 0 1
c
c ---- Separate cell source ---
SI14 22.8 27.2
SP14 0 1
SI15 -2.2 2.2
SP15 0 1
SI16 -2.2 2.2
SP16 0 1
It's always tricky trying to do so without much context.

Is there a proper way of performing this task without resorting to custom built subroutines?

Question summary
I wrote an excel macro in VBA that imports a large text file, reads each individual line to determine number of data to store, allocates the correct size for an array to hold the data, and then opens the file a second time to write the data into the array.
The problem I encountered with this program was the large text file has inconsistent tab sizes line for line. I had to write a special delimit filter function to select the correct data to store into the array.
Is there a proper way of performing this task without resorting to custom built subroutines?
Program specs
The program must perform data analysis for best fit with the following model $y_k = c_1 x_k + c_0 + c_{-1}(x_{k})^{-1}$, which includes a negative exponent. The program cannot allow the data to be left in the Excel spreadsheet after exit, however that does not mean it cannot be placed their temporarily. Performance and speed are important for the impatient user. The data imported can have unspecified number of repeating column types and undefined tab length delimits.
Open to suggestions
I am open to the idea of exploiting predefined excel functions and storing the data in excel variables temporally.
Determine size of data from text file
Dim LineText As String ' indiviudal line of row text from data file
Dim runs As Long ' number of delimited column of data we're interested in
Dim count As Long ' number rows in data file
Dim data() As Double 'data from text file
Dim i As Long ' array index
iF1 = FreeFile ' Returns an Integer representing the next file number available for use by the Open statement.
Open MyFile For Input As #iF1 'open data file first time
Line Input #iF1, LineText ' skip first line
Line Input #iF1, LineText ' read second line
runs = Len(LineText) - Len(Replace(LineText, "T", "")) ' number of occurences of character T
count = 0
While Not EOF(iF1) 'EOF means 'end of file'
Line Input #iF1, LineText
count = count + 1
Wend ' end of while loop
Close #iF1 'close text file
ReDim data(count, 2) 'resize 'data' array to number of rows in text file
reopen text file and store all data to array
Open MyFile For Input As #iF1 ' reopen data file second time
Line Input #iF1, LineText ' skip first line
Line Input #iF1, LineText ' skip second line
i = 1 'set index to first element in array
While Not EOF(iF1) 'EOF means 'end of file'
Line Input #iF1, LineText 'read line from text
data(i, 1) = Val(delimit_extract(LineText, 4 * runs - 0)) ' frequnecy data
data(i, 2) = Val(delimit_extract(LineText, 4 * runs - 2)) ' voltage data
i = i + 1 'update array index
Wend ' end of while loop
Close #iF1 'close text file
delimit_extract function
Private Function delimit_extract(text As String, x As Long) As String
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''function finds xth number in string text regardless of tab size
''x is the xth number desired in text
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim c As String ' holds indiviudal characters from text
Dim i_start As Long 'stores first index of recently discovered number
Dim i_end As Long 'stores last index of recently discovered number
Dim x_count As Long 'tallies current count of numbers discovered in text
Dim flag As Boolean ' flags true if first index of new number false otherwise
i_start = 1
i_end = 1
x_count = 0
flag = True 'set flag true for possible discovery of new number
For i = 1 To Len(text) ' loop through all characters in text
c = Mid(text, i, 1) 'extract individual character from text
If (c = ".") Or (c = "-") Or (c = "E") Or ((Asc(0) <= Asc(c)) And (Asc(c) <= Asc(9))) Then 'if character is related to a number
If flag = True Then 'catch new number discovered
x_count = x_count + 1 '' update total number of numbers discovered
i_start = i ' mark location of number in string
flag = False ' set recently discovered number to false
End If
i_end = i 'mark last known index of recently discovered number
Else
flag = True 'set flag true for possible discovery of new number
If (x_count = x) Then 'if total discovered numbers equals desired number
Exit For
End If
End If
Next i
delimit_extract = Mid(text, i_start, i_end - i_start + 1)
End Function
sample of data text file
Run #1 Run #1 Run #1 Run #1 Run #1 Run #2 Run #2 Run #2 Run #2 Run #2
Time (s) Voltage (V) Output Frequency (Hz) Calc3 (units) w Time (s) Voltage (V) Output Frequency (Hz) Calc3 (units) w
0.000 -0.060 69.940 0.00 0.00 0.000 0.034 29.980 0.00 0.00
5.000E-5 -0.024 1.26E-6 0.05 5.000E-5 0.078 1.26E-6 0.05
1.000E-4 0.059 2.51E-6 0.10 1.000E-4 -0.045 2.51E-6 0.10
1.500E-4 0.008 3.77E-6 0.15 1.500E-4 -0.056 3.77E-6 0.15
2.000E-4 -0.051 5.03E-6 0.20 2.000E-4 0.055 5.03E-6 0.20
2.500E-4 0.008 6.28E-6 0.25 2.500E-4 0.039 6.28E-6 0.25
3.000E-4 0.047 7.54E-6 0.30 3.000E-4 -0.056 7.54E-6 0.30
3.500E-4 -0.013 8.80E-6 0.35 3.500E-4 -0.021 8.80E-6 0.35
4.000E-4 -0.035 1.01E-5 0.40 4.000E-4 0.055 1.01E-5 0.40
4.500E-4 0.023 1.13E-5 0.45 4.500E-4 0.007 1.13E-5 0.45
5.000E-4 0.028 1.26E-5 0.50 5.000E-4 -0.049 1.26E-5 0.50
5.500E-4 -0.024 1.38E-5 0.55 5.500E-4 0.007 1.38E-5 0.55
6.000E-4 -0.017 1.51E-5 0.60 6.000E-4 0.043 1.51E-5 0.60
6.500E-4 0.027 1.63E-5 0.65 6.500E-4 -0.013 1.63E-5 0.65
7.000E-4 0.011 1.76E-5 0.70 7.000E-4 -0.033 1.76E-5 0.70
7.500E-4 -0.026 1.88E-5 0.75 7.500E-4 0.022 1.88E-5 0.75
8.000E-4 -4.272E-4 2.01E-5 0.80 8.000E-4 0.027 2.01E-5 0.80
8.500E-4 0.026 2.14E-5 0.85 8.500E-4 -0.022 2.14E-5 0.85
9.000E-4 -0.001 2.26E-5 0.90 9.000E-4 -0.016 2.26E-5 0.90
9.500E-4 -0.019 2.39E-5 0.95 9.500E-4 0.026 2.39E-5 0.95
0.001 0.009 2.51E-5 1.00 0.001 0.009 2.51E-5 1.00
0.001 0.017 2.64E-5 1.05 0.001 -0.022 2.64E-5 1.05
0.001 -0.010 2.76E-5 1.10 0.001 -0.002 2.76E-5 1.10
0.001 -0.011 2.89E-5 1.15 0.001 0.023 2.89E-5 1.15
0.001 0.013 3.02E-5 1.20 0.001 -0.002 3.02E-5 1.20
0.001 0.010 3.14E-5 1.25 0.001 -0.017 3.14E-5 1.25
0.001 -0.011 3.27E-5 1.30 0.001 0.007 3.27E-5 1.30
0.001 -0.002 3.39E-5 1.35 0.001 0.017 3.39E-5 1.35
0.001 0.013 3.52E-5 1.40 0.001 -0.008 3.52E-5 1.40
0.001 0.003 3.64E-5 1.45 0.001 -0.010 3.64E-5 1.45
0.002 -0.009 3.77E-5 1.50 0.002 0.012 3.77E-5 1.50
0.002 0.004 3.90E-5 1.55 0.002 0.010 3.90E-5 1.55
0.002 0.012 4.02E-5 1.60 0.002 -0.010 4.02E-5 1.60
0.002 -0.001 4.15E-5 1.65 0.002 -0.004 4.15E-5 1.65
0.002 -0.008 4.27E-5 1.70 0.002 0.012 4.27E-5 1.70
0.002 0.005 4.40E-5 1.75 0.002 0.004 4.40E-5 1.75
0.002 0.007 4.52E-5 1.80 0.002 -0.010 4.52E-5 1.80
0.002 -0.004 4.65E-5 1.85 0.002 0.003 4.65E-5 1.85
0.002 -0.001 4.78E-5 1.90 0.002 0.010 4.78E-5 1.90
0.002 0.005 4.90E-5 1.95 0.002 -0.002 4.90E-5 1.95
0.002 0.004 5.03E-5 2.00 0.002 -0.005 5.03E-5 2.00
0.002 -0.005 5.15E-5 2.05 0.002 0.006 5.15E-5 2.05
0.002 -9.155E-4 5.28E-5 2.10 0.002 0.006 5.28E-5 2.10
0.002 0.005 5.40E-5 2.15 0.002 -0.003 5.40E-5 2.15
Maybe this will help:
Function extractNumbers(line As String) As Variant
Dim v As Variant
Dim n As Long, i As Long
Dim c As New Collection
v = Split(line)
For i = LBound(v) To UBound(v)
If Len(v(i)) > 0 And IsNumeric(v(i)) Then c.Add v(i)
Next i
n = c.Count
If n = 0 Then Exit Function
v = Empty
ReDim v(0 To n - 1)
For i = 0 To n - 1
v(i) = CDbl(c.Item(i + 1))
Next i
extractNumbers = v
End Function
Sub test(line As String)
Dim i As Long
Dim s As String
Dim v As Variant
v = extractNumbers(line)
If Not IsEmpty(v) Then
For i = 0 To UBound(v)
s = s & " " & v(i)
Next i
Debug.Print Trim(s)
Else
Debug.Print "No numbers found"
End If
End Sub
Typical output:
test "Run #1 Run #1 Run #1 Run #1 Run #1 Run #2 Run #2 Run #2 Run #2 Run #2"
No numbers found
test "5.000E-5 -0.024 1.26E-6 0.05 5.000E-5 0.078 1.26E-6 0.05"
0.00005 -0.024 0.00000126 0.05 0.00005 0.078 0.00000126 0.05
test "5.000E-5 -0.024 bob 1.26E-6 0.05 5.000E-5 0.078 1.26E-6 0.05"
0.00005 -0.024 0.00000126 0.05 0.00005 0.078 0.00000126 0.05
Can you use this?
Option Explicit
Public Sub SpecesToTabs()
Const MAX_SPACES As Long = 10
Const FILE_NAME As String = "C:\test.txt"
Dim fso As Object, txt As Object, dat As String, i As Long
Set fso = CreateObject("Scripting.FileSystemObject")
Set txt = fso.OpenTextFile(FILE_NAME) 'open file for reading
dat = txt.ReadAll 'read entire file
If Len(dat) > 0 Then
For i = MAX_SPACES To 2 Step -1
dat = Replace(dat, Space(i), vbTab) 'replace space sets with tabs
Next
Set txt = fso.OpenTextFile(FILE_NAME, 2) 'open file for writing
txt.Write dat 'write back to text file"
End If
End Sub
This is what the structure of the tab delimited file will be:
.
You could get access to (and process) each element of data using Split
dat = Split(dat, vbCrLf) 'generates an array of lines
dat = Split(dat, vbTab) 'generates an array of data items for each line

Resources