In [1]:
import pandas as pd

In [2]:
Table = pd.read_csv('C:\Users\Ty Dickinson\Downloads\SevereStormsUpdated.csv', low_memory=False)
Table['BEGIN_DATE'] = pd.to_datetime(Table.BEGIN_DATE)

#adding new columns based on adjustments from existing columns
Table['Total_Damages'] = Table['DAMAGE_PROPERTY_NUM'] + Table['DAMAGE_CROPS_NUM']
Table['Z_Time'] = Table['BEGIN_TIME']
Table['Z_Day'] = Table['BEGIN_DATE']

pd.options.mode.chained_assignment = None

#ensuring that a blank cell is read as a 0 for later addition.
for i in range(0, len(Table.TOR_LENGTH)):
    if Table.TOR_LENGTH[i] == ' ':
        Table.TOR_LENGTH[i] = 0.0
for i in range(0, len(Table.TOR_WIDTH)):
    if Table.TOR_WIDTH[i] == ' ':
        Table.TOR_WIDTH[i] = 0.0
for i in range(0, len(Table.MAGNITUDE)):
    if Table.MAGNITUDE[i] == ' ':
        Table.MAGNITUDE[i] = 0
         
Table.TOR_LENGTH = Table.TOR_LENGTH.astype(float)  
Table.TOR_WIDTH = Table.TOR_WIDTH.astype(float)
Table.DEATHS_DIRECT = Table.DEATHS_DIRECT.astype(int)
Table.INJURIES_DIRECT = Table.INJURIES_DIRECT.astype(int)
Table.MAGNITUDE = Table.MAGNITUDE.astype(float)
Table.BEGIN_TIME = Table.BEGIN_TIME.astype(int)

#converting CST to Z 
for i in range(0, len(Table.BEGIN_TIME)):
    if Table.BEGIN_TIME[i] <= 1759:
        Table.Z_Time[i] = Table.BEGIN_TIME[i] + 600
        Table.Z_Day[i] = Table.BEGIN_DATE[i]
    else:
        Table.Z_Time[i] = (Table.BEGIN_TIME[i] + 600) - 2400
        Table.Z_Day[i] = Table.BEGIN_DATE[i] + pd.DateOffset(days=1)

#Defining lists to use for each indicator
WinterReports = []
SpringReports = []
SummerReports = []
FallReports = []

WinterDeath = []
SpringDeath = []
SummerDeath = []
FallDeath = []

WinterInjury = []
SpringInjury = []
SummerInjury = []
FallInjury = []

WinterCost = []
SpringCost = []
SummerCost = []
FallCost = []

WinterReportDaysList = []
SpringReportDaysList = []
SummerReportDaysList = []
FallReportDaysList = []

WinterTornadoWidth = []
SpringTornadoWidth = []
SummerTornadoWidth = []
FallTornadoWidth = []

WinterTornadoTrack = []
SpringTornadoTrack = []
SummerTornadoTrack = []
FallTornadoTrack = []

WinterHailMax = []
SpringHailMax = []
SummerHailMax = []
FallHailMax = []

WinterWindMax = []
SpringWindMax = []
SummerWindMax = []
FallWindMax = []

#setting the index as date to use the df.loc expression 
df = Table.set_index(['BEGIN_DATE'])

#defining date ranges and converting them to a Datetime data type
Date1 = pd.to_datetime('12-01-1980')
Date2 = pd.to_datetime('02-28-1981')
Date3 = pd.to_datetime('03-01-1981')
Date4 = pd.to_datetime('05-31-1981')
Date5 = pd.to_datetime('06-01-1981')
Date6 = pd.to_datetime('08-31-1981')
Date7 = pd.to_datetime('09-01-1981')
Date8 = pd.to_datetime('11-30-1981')
WinterCount = 0
SpringCount = 0
SummerCount = 0
FallCount = 0

#while statements to cycle through seasons and calculate reports, report days, fatalities, injuries
#damages, maximum hail size, maximum wind magnitude, maximum tornado width, and total tornado path length
while WinterCount <= 29:
    x = df.loc[Date1:Date2]
    maxes = x.groupby(['EVENT_TYPE']).max()
    WinterReports.insert(WinterCount,len(x.index))
    y = x.DEATHS_DIRECT.sum()
    WinterDeath.insert(WinterCount,y)
    z = x.INJURIES_DIRECT.sum()
    WinterInjury.insert(WinterCount,z)
    a = x.TOR_LENGTH.sum()
    WinterTornadoTrack.insert(WinterCount,a)
    if not len(x.index) == 0 :
        b = max(x.TOR_WIDTH)
        WinterTornadoWidth.insert(WinterCount,b)
    else: 
        WinterTornadoWidth.insert(WinterCount,0)
    c = x.Total_Damages.sum()
    WinterCost.insert(WinterCount,c)
    
    #These try statements are for finding the maximum magnitude for wind and hail. 
    #If there are no wind/hail reports, a KeyError is raised and then its value in the list is 0
    #If there are no reports for the season at all, the values are set at 0 in the else block
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Hail']
            WinterHailMax.insert(WinterCount,d)
        else: 
            WinterHailMax.insert(WinterCount,0)
    except KeyError:
        WinterHailMax.insert(WinterCount,0)
        
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Thunderstorm Wind']
            WinterWindMax.insert(WinterCount,d)
        else: 
            WinterWindMax.insert(WinterCount,0)
    except KeyError:
        WinterWindMax.insert(WinterCount,0)
    
    WinterReportDays = 1
    #nested if statements to calculate report days based on 12Z to 12Z the next day as 1 day
    if len(x.index) == 0:
        WinterReportDaysList.insert(WinterCount, 0)
    else: 
        for i in range(1, len(x.index)):
            if ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] < 1200))):
                continue
            elif ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] >= 1200) and (x.Z_Time[i-1] >= 1200))):
                continue
            elif (x.Z_Day[i] == (x.Z_Day[i-1] + pd.DateOffset(days=1))) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] >= 1200)):
                continue
            else:
                WinterReportDays = WinterReportDays + 1
        WinterReportDaysList.insert(WinterCount, WinterReportDays)
     
    #if the year was a leap year, then this sets the end date back to Feb. 28
    if Date2.is_leap_year:
        Date2 = Date2 - pd.DateOffset(days=1)
    #adds a year to the end date range for the next cycle of the while statement
    Date1 = Date1 + pd.DateOffset(years=1)
    Date2 = Date2 + pd.DateOffset(years=1)
    #if the upcoming year is a leap year, add 1 day to account for Feb. 29
    if Date2.is_leap_year:
        Date2 = Date2 + pd.DateOffset(days=1)
    WinterCount = WinterCount + 1
    
while SpringCount <= 29:
    x = df.loc[Date3:Date4]
    maxes = x.groupby(['EVENT_TYPE']).max()
    SpringReports.insert(SpringCount,len(x.index))
    y = x.DEATHS_DIRECT.sum()
    SpringDeath.insert(SpringCount,y)
    z = x.INJURIES_DIRECT.sum()
    SpringInjury.insert(SpringCount,z)
    a = x.TOR_LENGTH.sum()
    SpringTornadoTrack.insert(SpringCount,a)
    b = max(x.TOR_WIDTH)
    SpringTornadoWidth.insert(SpringCount,b)
    c = x.Total_Damages.sum()
    SpringCost.insert(WinterCount,c)
    
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Hail']
            SpringHailMax.insert(WinterCount,d)
        else: 
            SpringHailMax.insert(WinterCount,0)
    except KeyError:
        SpringHailMax.insert(WinterCount,0)
        
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Thunderstorm Wind']
            SpringWindMax.insert(WinterCount,d)
        else: 
            SpringWindMax.insert(WinterCount,0)
    except KeyError:
        SpringWindMax.insert(WinterCount,0)
    
    SpringReportDays = 1
    if len(x.index) == 0:
        SpringReportDaysList.insert(SpringCount, 0)
    else: 
        for i in range(1, len(x.index)):
            if ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] < 1200))):
                continue
            elif ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] >= 1200) and (x.Z_Time[i-1] >= 1200))):
                continue
            elif (x.Z_Day[i] == (x.Z_Day[i-1] + pd.DateOffset(days=1))) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] >= 1200)):
                continue
            else:
                SpringReportDays = SpringReportDays + 1
        SpringReportDaysList.insert(SpringCount, SpringReportDays)
    Date3 = Date3 + pd.DateOffset(years=1)
    Date4 = Date4 + pd.DateOffset(years=1)
    SpringCount = SpringCount + 1
    
while SummerCount <= 29:
    x = df.loc[Date5:Date6]
    maxes = x.groupby(['EVENT_TYPE']).max()
    SummerReports.insert(SummerCount,len(x.index))
    y = x.DEATHS_DIRECT.sum()
    SummerDeath.insert(SummerCount,y)
    z = x.INJURIES_DIRECT.sum()
    SummerInjury.insert(SummerCount,z)
    a = x.TOR_LENGTH.sum()
    SummerTornadoTrack.insert(SummerCount,a)
    if not len(x.index) == 0 :
        b = max(x.TOR_WIDTH)
        SummerTornadoWidth.insert(WinterCount,b)
    else: 
        SummerTornadoWidth.insert(WinterCount,0)
    c = x.Total_Damages.sum()
    SummerCost.insert(SummerCount,c)
    
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Hail']
            SummerHailMax.insert(WinterCount,d)
        else: 
            SummerHailMax.insert(WinterCount,0)
    except KeyError:
        SummerHailMax.insert(WinterCount,0)
        
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Thunderstorm Wind']
            SummerWindMax.insert(WinterCount,d)
        else: 
            SummerWindMax.insert(WinterCount,0)
    except KeyError:
        SummerWindMax.insert(WinterCount,0)
    
    SummerReportDays = 1
    if len(x.index) == 0:
        SummerReportDaysList.insert(SummerCount, 0)
    else: 
        for i in range(1, len(x.index)):
            if ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] < 1200))):
                continue
            elif ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] >= 1200) and (x.Z_Time[i-1] >= 1200))):
                continue
            elif (x.Z_Day[i] == (x.Z_Day[i-1] + pd.DateOffset(days=1))) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] >= 1200)):
                continue
            else:
                SummerReportDays = SummerReportDays + 1
        SummerReportDaysList.insert(SummerCount, SummerReportDays)
    Date5 = Date5 + pd.DateOffset(years=1)
    Date6 = Date6 + pd.DateOffset(years=1)
    SummerCount = SummerCount + 1
    
while FallCount <= 29:
    x = df.loc[Date7:Date8]
    maxes = x.groupby(['EVENT_TYPE']).max()
    FallReports.insert(FallCount,len(x.index))
    y = x.DEATHS_DIRECT.sum()
    FallDeath.insert(FallCount,y)
    z = x.INJURIES_DIRECT.sum()
    FallInjury.insert(FallCount,z)
    a = x.TOR_LENGTH.sum()
    FallTornadoTrack.insert(FallCount,a)
    b = max(x.TOR_WIDTH)
    FallTornadoWidth.insert(FallCount,b)
    c = x.Total_Damages.sum()
    FallCost.insert(FallCount,c)
    
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Hail']
            FallHailMax.insert(WinterCount,d)
        else: 
            FallHailMax.insert(WinterCount,0)
    except KeyError:
        FallHailMax.insert(WinterCount,0)
        
    try:
        if not len(x.index) == 0:
            d = maxes.MAGNITUDE['Thunderstorm Wind']
            FallWindMax.insert(WinterCount,d)
        else: 
            FallWindMax.insert(WinterCount,0)
    except KeyError:
        FallWindMax.insert(WinterCount,0)
    
    FallReportDays = 1
    if len(x.index) == 0:
        FallReportDaysList.insert(FallCount, 0)
    else: 
        for i in range(1, len(x.index)):
            if ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] < 1200))):
                continue
            elif ((x.Z_Day[i] == x.Z_Day[i-1]) and ((x.Z_Time[i] >= 1200) and (x.Z_Time[i-1] >= 1200))):
                continue
            elif (x.Z_Day[i] == (x.Z_Day[i-1] + pd.DateOffset(days=1))) and ((x.Z_Time[i] < 1200) and (x.Z_Time[i-1] >= 1200)):
                continue
            else:
                FallReportDays = FallReportDays + 1
        FallReportDaysList.insert(FallCount, FallReportDays)
    Date7 = Date7 + pd.DateOffset(years=1)
    Date8 = Date8 + pd.DateOffset(years=1)
    FallCount = FallCount + 1
    
#TO TEST IF THE LISTS ADD UP TO THE CORRECT AMOUNTS FROM THE CSV
#print(sum(WinterReports) + sum(SpringReports) + sum(SummerReports) + sum(FallReports))
#print(len(Table.index))
#print(sum(WinterDeath) + sum(SpringDeath) + sum(SummerDeath) + sum(FallDeath))
#print(Table.DEATHS_DIRECT.sum())
#print(sum(WinterInjury) + sum(SpringInjury) + sum(SummerInjury) + sum(FallInjury))
#print(Table.INJURIES_DIRECT.sum())
#print(sum(WinterTornadoTrack) + sum(SpringTornadoTrack) + sum(SummerTornadoTrack)+ sum(FallTornadoTrack))
#print(Table.TOR_LENGTH.sum())
#print(sum(WinterCost) + sum(SpringCost) + sum(SummerCost) + sum(FallCost))
#print(Table.Total_Damages.sum())


#Create dataframes for each list
df1 = pd.DataFrame({'Winter Reports': WinterReports})
df2 = pd.DataFrame({'Spring Reports': SpringReports})
df3 = pd.DataFrame({'Summer Reports': SummerReports})
df4 = pd.DataFrame({'Fall Reports': FallReports})
df5 = pd.DataFrame({'Winter Report Days': WinterReportDaysList})
df6 = pd.DataFrame({'Spring Report Days': SpringReportDaysList})
df7 = pd.DataFrame({'Summer Report Days': SummerReportDaysList})
df8 = pd.DataFrame({'Fall Report Days': FallReportDaysList})
df9 = pd.DataFrame({'Winter Fatalities': WinterDeath})
df10 = pd.DataFrame({'Spring Fatalities': SpringDeath})
df11 = pd.DataFrame({'Summer Fatalities': SummerDeath})
df12 = pd.DataFrame({'Fall Fatalities': FallDeath})
df13 = pd.DataFrame({'Winter Injuries': WinterInjury})
df14 = pd.DataFrame({'Spring Injuries': SpringInjury})
df15 = pd.DataFrame({'Summer Injuries': SummerInjury})
df16 = pd.DataFrame({'Fall Injuries': FallInjury})
df17 = pd.DataFrame({'Winter Tornado Track': WinterTornadoTrack})
df18 = pd.DataFrame({'Spring Tornado Track': SpringTornadoTrack})
df19 = pd.DataFrame({'Summer Tornado Track': SummerTornadoTrack})
df20 = pd.DataFrame({'Fall Tornado Track': FallTornadoTrack})
df21 = pd.DataFrame({'Winter Damages': WinterCost})
df22 = pd.DataFrame({'Spring Damages': SpringCost})
df23 = pd.DataFrame({'Summer Damages': SummerCost})
df24 = pd.DataFrame({'Fall Damages': FallCost})
df25 = pd.DataFrame({'Winter Largest Hail': WinterHailMax})
df26 = pd.DataFrame({'Spring Largest Hail': SpringHailMax})
df27 = pd.DataFrame({'Summer Largest Hail': SummerHailMax})
df28 = pd.DataFrame({'Fall Largest Hail': FallHailMax})
df29 = pd.DataFrame({'Winter Strongest Wind': WinterWindMax})
df30 = pd.DataFrame({'Spring Strongest Wind': SpringWindMax})
df31 = pd.DataFrame({'Summer Strongest Wind': SummerWindMax})
df32 = pd.DataFrame({'Fall Strongest Wind': FallWindMax})
df33 = pd.DataFrame({'Winter Widest Tornado': WinterTornadoWidth})
df34 = pd.DataFrame({'Spring Widest Tornado': SpringTornadoWidth})
df35 = pd.DataFrame({'Summer Widest Tornado': SummerTornadoWidth})
df36 = pd.DataFrame({'Fall Widest Tornado': FallTornadoWidth})

#concatenate the dataframes together
dftot = pd.concat([
    df1, df2, df3, df4, df5, df6, df7, df8, df9, df10,
    df11, df12, df13, df14, df15, df16, df17, df18, df19, df20,
    df21, df22, df23, df24, df25, df26, df27, df28, df29, df30,
    df31, df32, df33, df34, df35, df36
], axis=1)

years = []
for i in range(1981,2011):
    years.insert(i,i)
dftot = dftot.set_index([years])

#export to csv
dftot.to_csv('Severe Weather Impacts.csv')

In [ ]: