r/learnpython•
beauSnow

Weighted average scheme for a dictionary of dictionaries of lists

I have a function that takes ~ 100 data collection site's soil moisture data (at various depths; 2in, 4in, 8in, 20in, and 40in). Each site's soil moisture sensors (SMS) data needs to be reduced to a single value via a weighting scheme. Some sites have all five sensors, some have 3, etc. The dictionary structure is a dict of the sensor depths contains a dict of each sites data as a list. Or - {depth:{siteID:[data]}}. Id like the output to be a dictionary of the siteIds and the weighted data, or - {siteID:[weightedData]}. *edit, weighted data as a list

Here's what I came up with but I feel like it's garbage.

def calcSMSAvg(dataSMS):
    smsAllAvg = {}
    allSites = list(dataSMS[-2].keys())
    for smsSite in allSites:
        sms40 = []
        sms20 = []
        sms8 = []
        sms4 = []
        sms2 = []
        if dataSMS[-40]: sms40 = list(dataSMS[-40][smsSite])
        if dataSMS[-20]: sms20 = list(dataSMS[-20][smsSite])
        if dataSMS[-8]: sms8 = list(dataSMS[-8][smsSite])
        if dataSMS[-4]: sms4 = list(dataSMS[-4][smsSite])
        if dataSMS[-2]: sms2 = list(dataSMS[-2][smsSite])
        if sms2 and sms4 and sms8 and sms20 and sms40:
            sms40[:] = [np.asarray(x)*(15/50) if x != np.nan else
                 np.nan for x in sms40]
            sms20[:] = [np.asarray(x)*(15/50) if x != np.nan else
                 np.nan for x in sms20]
            sms8[:] = [np.asarray(x)*(10/50) if x != np.nan else
                np.nan for x in sms8]
            sms4[:] = [np.asarray(x)*(5/50) if x != np.nan else
                np.nan for x in sms4]
            sms2[:] = [np.asarray(x)*(5/50) if x != np.nan else
                np.nan for x in sms2]
            smsAll = list([sms40,sms20,sms8,sms4,sms2])
            smsAvg = [sum(x) for x in zip(*smsAll)]
        elif sms2 and sms8 and sms20:
            sms20[:] = [np.asarray(x)*(12/26) if x != np.nan else
                 np.nan for x in sms20]
            sms8[:] = [np.asarray(x)*(9/26) if x != np.nan else
                np.nan for x in sms8]
            sms2[:] = [np.asarray(x)*(5/26) if x != np.nan else
                np.nan for x in sms2]
            smsAll = list([sms20,sms8,sms2])
            smsAvg = [sum(x) for x in zip(*smsAll)]
        elif sms2 and sms8:
            sms8[:] = [np.asarray(x)*(1/2) if x != np.nan else
                np.nan for x in sms8]
            sms2[:] = [np.asarray(x)*(1/2) if x != np.nan else
                np.nan for x in sms2]
            smsAll = list([sms8,sms2])
            smsAvg = [sum(x) for x in zip(*smsAll)]
        elif sms20 and sms8:
            sms8[:] = [np.asarray(x)*(1/2) if x != np.nan else
                np.nan for x in sms8]
            sms20[:] = [np.asarray(x)*(1/2) if x != np.nan else
                np.nan for x in sms20]
            smsAll = list([sms8,sms20])
            smsAvg = [sum(x) for x in zip(*smsAll)]
        elif sms20 and sms2:
            sms2[:] = [np.asarray(x)*(1/2) if x != np.nan else
                np.nan for x in sms2]
            sms20[:] = [np.asarray(x)*(1/2) if x != np.nan else
                np.nan for x in sms20]
            smsAll = list([sms2,sms20])
            smsAvg = [sum(x) for x in zip(*smsAll)]
        else:
            smsAvg = []
        smsAllAvg.update({str(smsSite) : list(smsAvg)})
    return smsAllAvg

Posted Apr 26, 2017, 5:36 PM UTC

00
Loading comments…