Я работаю над заполнением отсутствующих данных в большом (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, и я думаю, что это определенно можно сделать более гладким способом, чем я делал здесь. Спасибо за любые предложения или комментарии,