具有NaN的Python去趋势3D数据集

时间:2018-07-12 04:54:18

标签: python python-3.x numpy scipy signal-processing

我正在尝试消除480x2040 =接近1,000,000像素大小的数据集的趋势。 我在这个系列(年)中有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])

干杯!

1 个答案:

答案 0 :(得分:0)

我不确定是否可以使signal.detrend基于数组跳过NaN。但是,您可以使用某种方法来填充丢失的数据,然后进行趋势下降。如果缺少的数据点很少,则其影响应该可以忽略不计。

由于各大洲始终是NaN,因此您可以用一些特殊的标记值替换它们,因为无论如何您都不会担心它们会掉线。对于丢失的数据NaN,我建议使用pandas(这对时间序列非常有用)来填充丢失数据的各种方法。我将在这里使用最简单的方法-从先前已知的值中进行正向填充-但您也可以使用更复杂的方法,例如取相邻值的平均值或进行插值。

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)