Пример #1
0
def eof(x, transform=False):
    '''
    Empirical Orthogonal Function (EOF) analysis to finds both time series and spatial patterns.
    
    :param x: (*array_like*) Input 2-D array with space-time field.
    :param transform: (*boolean*) Do space-time transform or not. This transform will speed up
        the computation if the space location number is much more than time stamps.
        
    :returns: (EOF, E, PC) EOF: eigen vector 2-D array; E: eigen values 1-D array;
        PC: Principle component 2-D array.
    '''
    m, n = x.shape
    if transform:
        C = np.dot(x.T, x)
        E1, EOF1 = np.linalg.eig(C)
        EOF1 = EOF1[:, ::-1]
        E = E1[::-1]
        EOFa = np.dot(x, EOF1)
        EOF = np.zeros((m, n))
        for i in range(n):
            EOF[:, i] = EOFa[:, i] / np.sqrt(abs(E[i]))
        PC = np.dot(EOF.T, x)
        PC = PC[::-1, :]
    else:
        C = np.dot(x, x.T) / n
        E, EOF = np.linalg.eig(C)
        PC = np.dot(EOF.T, x)
        EOF = EOF[:, ::-1]
        PC = PC[::-1, :]
        E = E[::-1]
    return EOF, E, PC
Пример #2
0
def eof(x, svd=False, transform=False):
    '''
    Empirical Orthogonal Function (EOF) analysis to finds both time series and spatial patterns.
    
    :param x: (*array_like*) Input 2-D array with space-time field.
    :param svd: (*boolean*) Using SVD or eigen method.
    :param transform: (*boolean*) Do space-time transform or not. This transform will speed up
        the computation if the space location number is much more than time stamps. Only valid
        when ``svd=False``.
        
    :returns: (EOF, E, PC) EOF: eigen vector 2-D array; E: eigen values 1-D array;
        PC: Principle component 2-D array.
    '''
    has_nan = False
    if x.contains_nan():  #Has NaN value
        valid_idx = np.where(x[:, 0] != np.nan)[0]
        xx = x[valid_idx, :]
        has_nan = True
    else:
        xx = x

    m, n = xx.shape
    if svd:
        U, S, V = np.linalg.svd(xx)
        EOF = U
        C = np.zeros((m, n))
        for i in range(len(S)):
            C[i, i] = S[i]
        PC = np.dot(C, V)
        E = S**2 / n
    else:
        if transform:
            C = np.dot(xx.T, xx)
            E1, EOF1 = np.linalg.eig(C)
            EOF1 = EOF1[:, ::-1]
            E = E1[::-1]
            EOFa = np.dot(xx, EOF1)
            EOF = np.zeros((m, n))
            for i in range(n):
                EOF[:, i] = EOFa[:, i] / np.sqrt(abs(E[i]))
            PC = np.dot(EOF.T, xx)
        else:
            C = np.dot(xx, xx.T) / n
            E, EOF = np.linalg.eig(C)
            PC = np.dot(EOF.T, xx)
            EOF = EOF[:, ::-1]
            PC = PC[::-1, :]
            E = E[::-1]

    if has_nan:
        _EOF = np.ones(x.shape) * np.nan
        _PC = np.ones(x.shape) * np.nan
        _EOF[valid_idx, :] = -EOF
        _PC[valid_idx, :] = -PC
        return _EOF, E, _PC
    else:
        return EOF, E, PC
Пример #3
0
    def __init__(self, dataset, bw_method=None):
        self.dataset = np.atleast_2d(dataset)
        if not np.array(self.dataset).size > 1:
            raise ValueError("`dataset` input should have multiple elements.")

        self.dim, self.num_dp = np.array(self.dataset).shape
        isString = isinstance(bw_method, str)

        if bw_method is None:
            pass
        elif (isString and bw_method == 'scott'):
            self.covariance_factor = self.scotts_factor
        elif (isString and bw_method == 'silverman'):
            self.covariance_factor = self.silverman_factor
        elif (np.isscalar(bw_method) and not isString):
            self._bw_method = 'use constant'
            self.covariance_factor = lambda: bw_method
        elif callable(bw_method):
            self._bw_method = bw_method
            self.covariance_factor = lambda: self._bw_method(self)
        else:
            raise ValueError("`bw_method` should be 'scott', 'silverman', a "
                             "scalar or a callable")

        # Computes the covariance matrix for each Gaussian kernel using
        # covariance_factor().

        self.factor = self.covariance_factor()
        # Cache covariance and inverse covariance of the data
        if not hasattr(self, '_data_inv_cov'):
            self.data_covariance = np.atleast_2d(
                np.stats.cov(self.dataset, rowvar=1, bias=False))
            self.data_inv_cov = np.linalg.inv(self.data_covariance)

        self.covariance = self.data_covariance * self.factor**2
        self.inv_cov = self.data_inv_cov / self.factor**2
        self.norm_factor = np.sqrt(np.linalg.det(
            2 * np.pi * self.covariance)) * self.num_dp