Я пытаюсь изменить свой набор данных размером 480x2040 = около 1000000 пикселей. У меня 17 временных шагов в этой серии (лет), однако я хочу в какой-то момент перейти к ежедневным временным шагам. Этот код работает, но работает слишком медленно, чтобы работать.
Я чувствую, что scipy.signal.detrend может обрабатывать весь набор данных, однако у меня есть несколько NaN. В некоторых случаях NaN являются континентами, что означает наличие NaN на каждом временном шаге, однако в некоторых более редких случаях некоторые данные отсутствуют.
Как я могу изменить тенденцию каждого пикселя моей карты с течением времени, игнорируя / пропуская NaN? Это должно быть на несколько порядков быстрее, чем этот цикл.
for i in range(0,nlat):
for j in range(0,nlon):
pixel = ds[:,i,j]
b = ~np.isnan(pixel)
detrend[b,i,j]=signal.detrend(pixel[b])
Ваше здоровье!






Я не уверен, можно ли заставить signal.detrend пропускать NaN на основе массива. Однако вы можете использовать какой-либо метод для заполнения недостающих данных, а затем избавиться от тренда. Если у вас есть несколько пропущенных точек данных, эффект от этого должен быть незначительным.
Поскольку континенты всегда имеют NaN, вы можете заменить их каким-нибудь особым значением маркера, так как вы все равно не будете заботиться об их устранении. Для NaN отсутствующих данных я предлагаю использовать панды, который отлично подходит для таймсерий, для различных методов заполнения недостающих данных. Я буду использовать здесь самый простой - прямую заливку из ранее известных значений - но вы также можете использовать более сложные методы, такие как получение среднего значения соседних значений или интерполяция.
import scipy.signal as signal
import numpy as np
import pandas as pd
''' Construct fake data'''
# construct some map-like values
pix = np.random.randint(256, size=(10,20))
ds = np.zeros((10, pix.shape[0], pix.shape[1]))
for i in range(1,11):
ds[i-1,:,:] = i*pix
# 5% missing data
ds[(np.random.rand(10,10,20) < 0.05)] = np.nan
# a square continent
ds[:,1:3,5:10] = np.nan
''' Solution based on fake data'''
# assign some marker value to continents
ds[:, np.all(np.isnan(ds), axis=0)] = -1
df = pd.Panel(ds)
df.fillna(method='ffill', axis=0, inplace=True) # forward fill
df.fillna(method='bfill', axis=0, inplace=True) # backfill in case there are nans in first timestep
detrended = signal.detrend(df.values)
@NicPittman -1 был примером, вы можете использовать любое другое значение для NaN континента, которое соответствует вашим данным, то есть значение, которое, как вы знаете, в противном случае вы не встретите. NaN отсутствующих данных, конечно, не будет -1, а будет устанавливаться в соответствии с методом заполнения, который вы выбираете с помощью pandas.
Спасибо за ответ. Я не уверен на 100% в маркере -1 для значений NaN, но я попробую и посмотрю, что произойдет! Возможно, мне нужно будет сделать маску континента, чтобы я мог нанести их обратно на свой участок.