Skip to content
This repository was archived by the owner on Apr 30, 2021. It is now read-only.
This repository was archived by the owner on Apr 30, 2021. It is now read-only.

Least squares polynomial fit with Dask #144

@andersy005

Description

@andersy005

Per discussion with @matt-long, it would be useful to add a least squares polynomial fit to esmlab:

import xarray as xr
import dask.array as da 
def _order_and_stack(darr, dim):
    dims_stacked = [d for d in darr.dims if d != dim]
    new_dims = [dim, ] + dims_stacked
    if darr.ndim > 2:
        darr_stacked = (darr.transpose(*new_dims).stack(other_dims=dims_stacked).dropna('other_dims'))

    elif darr.ndim == 2:
        darr_stacked = darr_stacked.transpose(*new_dims)

    else:
        darr_stacked = darr

    return darr_stacked

def _unstack(darr):
    if 'other_dims' in darr.dims:
        darr_unstacked = darr.unstack('other_dims')

    else:
        darr_unstacked = darr

    return darr_unstacked

def _polyfit(darr, x, deg, dim):
    dim_chunk = darr.chunks[darr.get_axis_num(dim)][0]
    x = x.chunk(chunks={dim: dim_chunk, 'degree': deg + 1})
    darr_stacked = _order_and_stack(darr, dim)
    p, err, _, _ = da.linalg.lstsq(x.data, darr_stacked.data)
    new_name = f'{darr.name}_poly_coeffs'
    new_dims = ('degree',) + darr_stacked.dims[1:]
    new_coords = {coord: darr_stacked.coords[coord] for coord in darr_stacked.coords 
                  if coord != dim}
    lstsq_coeffs = xr.DataArray(p, name=new_name, coords=new_coords, dims=new_dims)
    return lstsq_coeffs



def polyfit(darr, deg=1, dim=None, coord=None):
    if not dim:
        dim = 'time'

    if not coord:
        coord = darr[dim]

    t = coord

    x = xr.concat([t ** d for d in range(deg + 1)], dim='degree')
    x = x.transpose(dim, 'degree')

    coeffs = _polyfit(darr, x, deg, dim)
    coeffs = coeffs.assign_coords(degree=range(deg + 1)) 
    return _unstack(coeffs)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions