@@ -0,0 +1,2098 @@
+from functools import partial  %0Afrom itertools import islice, product  %0Aimport numpy as np%0Aimport xarray as xr%0A%0Adef __where_not_nan(arr: np.ndarray):%0A    %22%22%22Finds position of not nan values in an nd-array%0A%0A    Args:%0A        arr (numpy.ndarray): nd-array with nan values%0A        %0A    Returns:%0A        data (xr.DataArray): nd-array with indices of finite(not nan) values%0A    %22%22%22%0A    return np.where(np.isfinite(arr))%0A%0A%0Adef __flatten_shallow(arr):%0A    %22%22%22Flattens first two axes of nd-array%0A    Args:%0A        arr (numpy.ndarray): nd-array with dimensions (n, m)%0A        %0A    Returns: %0A        arr (numpy.ndarray): nd-array with dimensions (n*m)%0A    %22%22%22%0A    # TODO: Done in a hurry, Find numpy native way of resizing %0A    return arr.reshape(arr.shape%5B0%5D * arr.shape%5B1%5D)%0A%0A%0Adef __linear_fit(da: xr.DataArray):%0A    %22%22%22Applies linear regression on a 1-D xr.DataArray. %0A%0A    Args:%0A        da (xr.DataArray): 1-D Data-Array being manipulated. %0A        %0A    Returns:%0A        data (xr.DataArray): DataArray with a single element(slope of regression).%0A    %22%22%22%0A    %0A    xs = np.array(list(range(len(da.time))))%0A    ys = __flatten_shallow(da.values)%0A        %0A    not_nan = __where_not_nan(ys)%5B0%5D.astype(int)%0A%0A    xs = xs%5Bnot_nan%5D%0A    ys = ys%5Bnot_nan%5D %0A%0A    pf = np.polyfit(xs,ys, 1)%0A    return xr.DataArray(pf%5B0%5D)%0A%0A%0Adef linear(da: xr.DataArray):%0A    %22%22%22Reduces xarray along a time component. The reduction yields a slope for each spatial coordinate in the xarray. %0A%0A    Args:%0A        da (xr.DataArray): 3-D Data-Array being manipulated. %60latitude%60 and %60longitude%60 are required dimensions.%0A%0A    Returns:%0A        linear_trend_product (xr.DataArray): 2-D Data-Array%0A    %22%22%22%0A%0A    # TODO: Decouple from coordinate system, and allow regression along multiple components.%0A    stacked = da.stack(allpoints = %5B'latitude',%0A                                    'longitude'%5D)%0A    %0A    trend = stacked.groupby('allpoints').apply(__linear_fit)%0A    %0A    unstacked = trend.unstack('allpoints')%0A    %0A    return unstacked.rename(dict(allpoints_level_0 = %22latitude%22,%0A                                 allpoints_level_1 = %22longitude%22))

Add linear-trend utility.