import os import sys import pandas as pd from pandas import Series from datetime import datetime pd.options.mode.chained_assignment = None # default='warn' pd.set_option('precision', 1) def lat_lon_to_float(v): # Convert strings from NHC file (Lat Lon with N/S and W/E to floats) if (v[-1] == 'S') or (v[-1] =='W'): multiplier = -1 else: multiplier = 1 return float(v[:-1]) * multiplier def convert_1d_to_2d(l, cols): return [l[i:i + cols] for i in range(0, len(l), cols)] SummaryList = [] RegionalACE =[] RegionalACE.append(['Year','MDRACE', 'GMXACE','EXTACE']) data = [] data2= [] with open('atl_hurdat.txt','r') as f: for line in f.readlines(): if line.startswith('AL'): storm_id =line.split(',') storm_id.pop() # storm_id_str=','.join([str(elem) for elem in storm_id]) storm_numberFull = storm_id[0].strip() storm_name = storm_id[1].strip() basin = storm_numberFull[0:2] storm_number = int(storm_numberFull[2:4]) storm_year = int(storm_numberFull[4:]) else: location_line = line.split(',') location_line.pop() # location_line_str=','.join([str(elem) for elem in location_line]) #print(location_line) dt = datetime.strptime(location_line[0]+ location_line[1], '%Y%m%d %H%M') dy = datetime.strptime(location_line[0], '%Y%m%d') jdy = dy.strftime("%j") jdy=int(jdy) hr = int(location_line[1][1:3]) mns = int(location_line[1][3:5]) lfall = location_line[2].strip() storm_status = location_line[3].strip() storm_lat = lat_lon_to_float(location_line[4].strip()) storm_lon = lat_lon_to_float(location_line[5].strip()) max_wind = int(location_line[6].strip()) data.append([basin, storm_number, storm_year, storm_name, storm_status, storm_lat, storm_lon, lfall, dt, dy, jdy, hr, mns, max_wind]) # data2.append([storm_id_str,location_line_str]) #bigdf=pd.DataFrame(data2,columns=['id','locline']) #s=bigdf['id'] #p=s.str.split(pat=",",expand=True) #s=bigdf['locline'] #t=s.str.split(pat=",",expand=True) #newBigdf=pd.concat([p,t],axis=1,join="inner") #print(newBigdf) #newBigdf.to_csv('./atl_hurdat.csv') df = pd.DataFrame(data, columns=['Basin','StormNumber', 'StormYear', 'StormName', 'StormStatus', 'Lat', 'Lon', 'LandFall','Date_Time', 'Day', 'JulDay', 'Hour', 'Minutes','MaxWind']) df['MaxWSqd']=df['MaxWind']*df['MaxWind'] df.drop(df[df['StormYear']<1950].index, inplace=True) #dfPost1950=df for status in ['TD','EX', 'LO','DB', 'SD', 'WV']: df.drop(df[(df['StormStatus'] == status)].index,inplace=True) print(df) Totallen=len(df['StormYear'].unique()) # Section to modify to pick off specific dat ranges df.drop(df[df['Day'].dt.month < 8].index,inplace=True) df.drop(df[df['Day'].dt.month > 8].index,inplace=True) print(df) years= df['StormYear'].unique() for yr in years: # print("\n"+str(yr)) dfYear=df[df['StormYear']==int(yr)] # print(dfYear.drop_duplicates(subset='StormName')) SSCount=0 MHCount=0 MDRACE=0 GMXACE=0 EXTACE=0 MDRCount=0 GMXCount=0 EXTCount=0 for num in dfYear['StormNumber'].unique(): dfByNum=dfYear[dfYear['StormNumber']==num] try: if(dfByNum['StormStatus'].value_counts().SS == dfByNum.shape[0]): SSCount=SSCount+1 except: pass if(len(dfByNum[dfByNum['MaxWind'] > 95])>0): MHCount=MHCount+1 Lat=dfByNum['Lat'].iloc[0] Lon=dfByNum['Lon'].iloc[0] # Now start filtering for ACE calculations # None of the off rows for landsfalls and such dfByNum.drop(dfByNum[dfByNum['Minutes'] != 0].index,inplace=True) # Only grab rows of 0,6,12,18 dfByNum.drop(dfByNum[dfByNum['Hour'].mod(6) != 0].index,inplace=True) StormACE=dfByNum.MaxWSqd.sum() StormACE=round((float(StormACE)/10000),2) if ((0 < Lat < 21) and (-90 < Lon < -20)): FormReg = "MDR" MDRCount = MDRCount + 1 MDRACE = MDRACE + StormACE elif ((Lat >= 21) and (Lon < -81) or (Lat >= 18) and (-100 < Lon < -90)): FormReg = "GMX" GMXCount = GMXCount + 1 GMXACE = GMXACE + StormACE else: FormReg = "EXT" EXTCount = EXTCount + 1 EXTACE = EXTACE + StormACE # print(dfByNum['StormName'].iloc[0], str(Lat), str(Lon), FormReg, str(round(StormACE,2)), round(MDRACE,2), round(GMXACE,2), round(EXTACE,2)) RegionalACE.append([str(yr),MDRACE,GMXACE,EXTACE]) dfHU=dfYear[dfYear['StormStatus']=='HU'] dfHU.drop_duplicates(subset='StormName',inplace=True) # print("SubTropStorms : "+str(SSCount)) # print("Named Storms : "+str(len(dfYear['StormNumber'].unique()))) # print("Hurricane : "+str(dfHU.shape[0])) # print("Major Hurricane: "+str(MHCount)) NamedStorms = len(dfYear['StormNumber'].unique()) HU=dfHU.shape[0] # Now start filtering for ACE calculations # None of the off rows for landsfalls and such dfYear.drop(dfYear[dfYear['Minutes'] != 0].index,inplace=True) # Only grab rows of 0,6,12,18 dfYear.drop(dfYear[dfYear['Hour'].mod(6) != 0].index,inplace=True) #print(dfYear) ACEwSS=round(dfYear['MaxWSqd'].sum()/10000,1) # print("ACE wSS : "+str(ACEwSS)) # print(str(yr),round(MDRACE,2), round(GMXACE,2), round(EXTACE,2),ACEwSS) SummaryList.append([yr,NamedStorms,HU, MHCount,ACEwSS]) #for vals in RegionalACE: # print(vals) print(RegionalACE) #print(convert_1d_to_2d(RegionalACE,1)) SummaryDF=pd.DataFrame(SummaryList,columns=['YEAR','NamedTS', 'HU', 'MH','ACE']) print(SummaryDF) SummaryDF = pd.concat([SummaryDF,SummaryDF.sum().to_frame().T], ignore_index=True) #print(SummaryDF) #os.system('more ./ATL_1950_Present_Stats.csv') SummaryDF.at[len(SummaryDF)-1,'YEAR']=0000.0 SummaryDF.at[len(SummaryDF)-1,'NamedTS']=(SummaryDF.at[len(SummaryDF)-1,'NamedTS'])/Totallen SummaryDF.at[len(SummaryDF)-1,'HU']=(SummaryDF.at[len(SummaryDF)-1,'HU'])/Totallen SummaryDF.at[len(SummaryDF)-1,'MH']=(SummaryDF.at[len(SummaryDF)-1,'MH'])/Totallen SummaryDF.at[len(SummaryDF)-1,'ACE']=(SummaryDF.at[len(SummaryDF)-1,'ACE'])/Totallen print(SummaryDF) SummaryDF.to_csv("./ATL_Aug_Stats.csv", index=False, float_format='%.1f')