Замена замаскированных данных предыдущими значениями того же набора данных - PullRequest
1 голос
/ 27 февраля 2020

Я работаю над заполнением отсутствующих данных в большом (4 ГБ) файле данных netcdf (3 измерения: время, долгота и широта). Метод заключается в заполнении замаскированных значений в data1 либо:

1) предыдущими значениями из data1 или

2) данными из другого (также замаскированного набора данных, data2), если найдено значение из данных1 <найденное значение из данных2. </p>

Итак, я попробовал пару вещей, одна из которых - создать очень сложный сценарий с длинными циклами для циклов, который никогда не заканчивался через 24 часа. Я пытался уменьшить это, но я думаю, что это все еще очень сложно. Я считаю, что есть гораздо более простая процедура, чем то, что я делаю сейчас, я просто не понимаю, как это сделать.

Я создал скрипт, в котором замаскированные данные сначала заменяются нулями, чтобы использовать функцию np.where для получения индекса моих замаскированных данных (я не нашел функцию, которая возвращает координаты замаскированных данных так что это моя работа вокруг этого). Моя проблема в том, что мой код очень длинный, и я думаю, что для выполнения больших наборов данных требуется много времени. Я считаю, что есть более простой способ сделать это, но я не нашел другой работы вокруг этого. Вот что у меня получилось:: (первая часть - просто сгенерировать несколько матриц, с которыми легко работать):

if __name__ == '__main__':
    import numpy as np
    import numpy.ma as ma
    from sortdata_helpers import decision_tree

    # Generating some (easy) test data to try the algorithm on:
    # data1
    rand1 = np.random.randint(10, size=(10, 10, 10))
    rand1 = ma.masked_where(rand1 > 5, rand1)
    rand1 = ma.filled(rand1, fill_value=0)
    rand1[0,:,:] = 1

    #data2
    rand2 = np.random.randint(10, size=(10, 10, 10))
    rand2[0, :, :] = 1
    coordinates1 = np.asarray(np.where(rand1 == 0)) # gives the locations of where in the data there are zeros

    filled_data = decision_tree(rand1, rand2, coordinates1)
    print(filled_data)

Вот те функции, которые я определил для вызова в основном скрипте: в том порядке, в котором они используются:

def decision_tree(data1, data2, coordinates):
    # This is the main function,
    # where the decision between data1 or data2 is chosen.
    import numpy as np
    from sortdata_helpers import generate_vector
    from sortdata_helpers import find_value

    for i in range(coordinates.shape[1]):
        coordinate = [coordinates[0, i], coordinates[1,i], coordinates[2,i]]
        AET_vec = generate_vector(data1, coordinate) # makes vector to go back in time
        AET_value = find_value(AET_vec) # Takes the vector and find closest day with data
        PET_vec =  generate_vector(data2, coordinate)
        PET_value = find_value(PET_vec)
        if PET_value > AET_value:
            data1[coordinate[0], coordinate[1], coordinate[2]] = AET_value
        else:
            data1[coordinate[0], coordinate[1], coordinate[2]] = PET_value
    return(data1)


def generate_vector(data, coordinate):
    # This one generates the vector to go back in time.
    vector = data[0:coordinate[0], coordinate[1], coordinate[2]]
    return(vector)

def find_value(vector):
    # Here the fist value in vector that is not zero is chosen as "value"
    from itertools import dropwhile
    value = list(dropwhile(lambda x: x == 0, reversed(vector)))[0]
    return(value)

Надеюсь, у кого-то есть хорошая идея или предложения по улучшению моего кода. Я все еще борюсь с пониманием индексации в python, и я думаю, что это определенно можно сделать более гладким способом, чем я делал здесь. Спасибо за любые предложения или комментарии,

...