mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
2666 lines
86 KiB
Python
2666 lines
86 KiB
Python
# coding=utf-8
|
||
#-----------------------------------------------------
|
||
# Author: Yaqiang Wang
|
||
# Date: 2014-12-27
|
||
# Purpose: MeteoInfo numerical module
|
||
# Note: Jython
|
||
#-----------------------------------------------------
|
||
import math
|
||
import cmath
|
||
import datetime
|
||
import numbers
|
||
from org.meteoinfo.data import GridData, GridArray, StationData, DataMath, TableData, TableUtil
|
||
from org.meteoinfo.math import ArrayMath, ArrayUtil
|
||
from org.meteoinfo.data.meteodata.netcdf import NetCDFDataInfo
|
||
from org.meteoinfo.math.interpolate import InterpUtil
|
||
from org.meteoinfo.ndarray import Array, Dimension
|
||
from org.meteoinfo.geoprocess import GeometryUtil
|
||
from org.meteoinfo.laboratory.util import JythonUtil
|
||
from org.python.core import PyComplex
|
||
|
||
from dimarray import PyGridData, DimArray, PyStationData
|
||
from multiarray import NDArray
|
||
from mitable import PyTableData
|
||
import mipylib.miutil as miutil
|
||
import _dtype
|
||
|
||
from java.lang import Math, Double, Float
|
||
from java.util import Calendar
|
||
|
||
# Global variables
|
||
pi = Math.PI
|
||
e = Math.E
|
||
inf = Double.POSITIVE_INFINITY
|
||
nan = Double.NaN
|
||
newaxis = None
|
||
|
||
__all__ = [
|
||
'pi','e','inf','nan','acos','absolute','all','any','arange','arange1',
|
||
'argmin','argmax','array','array_split','asanyarray','asarray','asgridarray','asgriddata','asin',
|
||
'asmiarray','asstationdata','atleast_1d','atleast_2d','atan','atan2','ave_month','average','histogram',
|
||
'broadcast_to','cdiff','ceil','concatenate','corrcoef','cos','cumsum','degrees','delete','delnan','diag',
|
||
'diff','dim_array','datatable','dot','empty','exp','eye','floor','fmax','fmin','full',
|
||
'griddata','hcurl','hdivg','hstack','identity','interp2d',
|
||
'interpn','isarray','isfinite','isinf','isnan','linint2','linregress','linspace','log','log10',
|
||
'logical_not','logspace','magnitude','max','maximum','mean','median','meshgrid','min','minimum',
|
||
'monthname','newaxis','nonzero','ones','ones_like','pol2cart','polyval','power','radians','ravel',
|
||
'reshape','repeat','rolling_mean','rot90','sin','shape','smooth5','smooth9','sort','squeeze','argsort',
|
||
'split','sqrt','square','std','sum','swapaxes','tan','tile','transpose','trapz','vdot','unique',
|
||
'unravel_index','var','vstack','where','zeros','zeros_like'
|
||
]
|
||
|
||
def isgriddata(gdata):
|
||
return isinstance(gdata, PyGridData)
|
||
|
||
def isstationdata(sdata):
|
||
return isinstance(sdata, PyStationData)
|
||
|
||
def array(object, dtype=None):
|
||
"""
|
||
Create an array.
|
||
|
||
:param object: (*array_like*) A Jython list or digital object.
|
||
:param dtype: (*DataType*) Data type
|
||
|
||
:returns: (*NDArray*) An array object satisfying the specified requirements.
|
||
|
||
Examples
|
||
|
||
::
|
||
|
||
>>> array([1,2,3])
|
||
array([1, 2, 3])
|
||
>>> array(25.6)
|
||
array([25.6])
|
||
|
||
More than one dimensions:
|
||
|
||
::
|
||
|
||
>>> array([[1,2], [3,4]])
|
||
array([[1.0, 2.0]
|
||
[3.0, 4.0]])
|
||
"""
|
||
if isinstance(object, NDArray):
|
||
return object
|
||
elif isinstance(object, Array):
|
||
return NDArray(object)
|
||
|
||
if isinstance(object, PyComplex):
|
||
return NDArray(JythonUtil.toComplexArray(object))
|
||
|
||
if isinstance(object, (list, tuple)):
|
||
if len(object) > 0:
|
||
if isinstance(object[0], datetime.datetime):
|
||
object = miutil.dates2nums(object)
|
||
elif isinstance(object[0], PyComplex):
|
||
return NDArray(JythonUtil.toComplexArray(object))
|
||
elif isinstance(object[0], (list, tuple)):
|
||
if isinstance(object[0][0], PyComplex):
|
||
return NDArray(JythonUtil.toComplexArray(object))
|
||
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
if not dtype is None:
|
||
dtype = dtype._dtype
|
||
|
||
return NDArray(ArrayUtil.array(object, dtype))
|
||
|
||
def dim_array(a, dims=None):
|
||
'''
|
||
Create a dimension array (DimArray).
|
||
|
||
:param a: (*array_like*) Array (NDArray) or data list.
|
||
:param dims: (*list*) List of dimensions.
|
||
|
||
:returns: (*DimArray*) Dimension array.
|
||
'''
|
||
if not isinstance(a, NDArray):
|
||
a = array(a)
|
||
if dims is None:
|
||
dims = []
|
||
for i in range(a.ndim):
|
||
dim = Dimension()
|
||
dim.setDimValues(range(a.shape[i]))
|
||
dims.append(dim)
|
||
return DimArray(a, dims)
|
||
|
||
def isarray(a):
|
||
'''
|
||
Check if input object is an array or not.
|
||
|
||
:param a: (*object*) Input object.
|
||
|
||
:returns: (*boolean*) True if the input object is an array.
|
||
'''
|
||
return isinstance(a, NDArray)
|
||
|
||
def datatable(data=None):
|
||
'''
|
||
Create a PyTableData object.
|
||
|
||
:param data: (*TableData*) Table data.
|
||
|
||
:returns: (*PyTableData*) PyTableData object.
|
||
'''
|
||
return PyTableData(data)
|
||
|
||
def arange(*args):
|
||
"""
|
||
Return evenly spaced values within a given interval
|
||
|
||
Values are generated within the half-open interval ``[start, stop]`` (in other words,
|
||
the interval including *start* but excluding *stop*).
|
||
|
||
When using a non-integer step, such as 0.1, the results will often not be consistent.
|
||
It is better to use ``linespace`` for these cases.
|
||
|
||
:param start: (*number, optional*) Start of interval. The interval includes this value.
|
||
The default start value is 0.
|
||
:param stop: (*number*) End of interval. The interval does not include this value,
|
||
except in some cases where *step* is not an integer and floating point round-off
|
||
affects the length of *out*.
|
||
:param step: (*number, optional*) Spacing between values. For any output *out*, this
|
||
is the distance between two adjacent values, ``out[i+1] - out[i]``. The default
|
||
step size is 1. If *step* is specified. *start* must also be given.
|
||
:param dtype: (*dtype*) The type of output array. If dtype is not given, infer the data
|
||
type from the other input arguments.
|
||
|
||
:returns: (*NDArray*) Array of evenly spaced values.
|
||
|
||
Examples::
|
||
|
||
>>> arange(3)
|
||
array([0, 1, 2])
|
||
>>> arange(3,7,2)
|
||
array([3, 5])
|
||
"""
|
||
if len(args) == 1:
|
||
start = 0
|
||
stop = args[0]
|
||
step = 1
|
||
elif len(args) == 2:
|
||
start = args[0]
|
||
stop = args[1]
|
||
step = 1
|
||
else:
|
||
start = args[0]
|
||
stop = args[1]
|
||
step = args[2]
|
||
return NDArray(ArrayUtil.arrayRange(start, stop, step))
|
||
|
||
def arange1(start, num=50, step=1):
|
||
"""
|
||
Return evenly spaced values within a given interval.
|
||
|
||
:param start: (*number*) Start of interval. The interval includes this value.
|
||
:param num: (*int*) Number of samples to generate. Default is 50. Must
|
||
be non-negative.
|
||
:param step: (*number*) Spacing between values. For any output *out*, this
|
||
is the distance between two adjacent values, ``out[i+1] - out[i]``. The default
|
||
step size is 1.
|
||
|
||
:returns: (*NDArray*) Array of evenly spaced values.
|
||
|
||
Examples::
|
||
|
||
>>> arange1(2, 5)
|
||
array([2, 3, 4, 5, 6])
|
||
>>> arange1(2, 5, 0.1)
|
||
array([2.0, 2.1, 2.2, 2.3, 2.4])
|
||
"""
|
||
return NDArray(ArrayUtil.arrayRange1(start, num, step))
|
||
|
||
def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
|
||
"""
|
||
Return evenly spaced numbers over a specified interval.
|
||
|
||
Returns *num* evenly spaced samples, calculated over the interval [*start, stop*].
|
||
|
||
The endpoint of the interval can optionally be excluded.
|
||
|
||
:param start: (*number*) Start of interval. The interval includes this value.
|
||
:param stop: (*number*) The end value of the sequence, unless endpoint is set to
|
||
False. In that case, the sequence consists of all but the last of ``num + 1``
|
||
evenly spaced samples, so that stop is excluded. Note that the step size changes
|
||
when endpoint is False.
|
||
:param num: (*int, optional*) Number of samples to generate. Default is 50. Must
|
||
be non-negative.
|
||
:param endpoint: (*boolean, optional*) If true, stop is the last sample. Otherwise, it is not included.
|
||
Default is True.
|
||
:param dtype: (*dtype*) The type of output array. If dtype is not given, infer the data
|
||
type from the other input arguments.
|
||
|
||
:returns: (*NDArray*) Array of evenly spaced values.
|
||
|
||
Examples::
|
||
|
||
>>> linspace(2.0, 3.0, num=5)
|
||
array([2.0, 2.25, 2.5, 2.75, 3.0])
|
||
>>> linspace(2.0, 3.0, num=5, endpoint=False)
|
||
array([2.0, 2.25, 2.5, 2.75])
|
||
"""
|
||
return NDArray(ArrayUtil.lineSpace(start, stop, num, endpoint))
|
||
|
||
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
|
||
"""
|
||
Return numbers spaced evenly on a log scale.
|
||
|
||
In linear space, the sequence starts at base ** start (*base to the power of start*) and ends with
|
||
base ** stop.
|
||
|
||
:param start: (*float*) Base ** start is the starting value of the sequence.
|
||
:param stop: (*float*) Base ** stop is the final value of the sequence, unless *endpoint* is False.
|
||
In that case, num + 1 values are spaced over the interval in log-space, of which all but the last
|
||
(a sequence of length num) are returned.
|
||
:param num: (*int, optional*) Number of samples to generate. Default is 50. Must
|
||
be non-negative.
|
||
:param endpoint: (*boolean, optional*) If true, stop is the last sample. Otherwise, it is not included.
|
||
Default is True.
|
||
:param base: (*float, optional*) The base of the log space. The step size between the elements in
|
||
ln(samples) / ln(base) (or log_base(samples)) is uniform. Default is 10.0.
|
||
:param dtype: (*dtype*) The type of output array. If dtype is not given, infer the data
|
||
type from the other input arguments.
|
||
|
||
:returns: (*NDArray*) Array of evenly spaced values.
|
||
|
||
Examples::
|
||
|
||
>>> logspace(2.0, 3.0, num=4)
|
||
array([100.0, 215.4434295785405, 464.1589682991224, 1000.0])
|
||
>>> logspace(2.0, 3.0, num=4, base=2.0)
|
||
array([4.0, 5.0396839219614975, 6.349604557649573, 8.0])
|
||
"""
|
||
r = NDArray(ArrayUtil.lineSpace(start, stop, num, endpoint))
|
||
r = pow(base, r)
|
||
return r
|
||
|
||
def empty(shape, dtype='float'):
|
||
"""
|
||
Create a new aray of given shape and type, without initializing entries.
|
||
|
||
:param shape: (*int or sequence of ints*) Shape of the new array, e.g., ``(2, 3)`` or ``2``.
|
||
:param dtype: (*data-type, optional*) The desired data-type for the array, including 'int',
|
||
'float' and 'double'.
|
||
|
||
:returns: (*NDArray*) Array of zeros with the given shape and dtype.
|
||
|
||
Examples::
|
||
|
||
>>> empty(5)
|
||
array([0.0, 0.0, 0.0, 0.0, 0.0])
|
||
>>> empty(5, dtype='int')
|
||
array([0, 0, 0, 0, 0])
|
||
>>> empty((2, 1))
|
||
array([[0.0]
|
||
[0.0]])
|
||
"""
|
||
shapelist = []
|
||
if isinstance(shape, int):
|
||
shapelist.append(shape)
|
||
else:
|
||
shapelist = shape
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.zeros(shapelist, dtype._dtype))
|
||
|
||
def zeros(shape, dtype='float'):
|
||
"""
|
||
Create a new aray of given shape and type, filled with zeros.
|
||
|
||
:param shape: (*int or sequence of ints*) Shape of the new array, e.g., ``(2, 3)`` or ``2``.
|
||
:param dtype: (*data-type, optional*) The desired data-type for the array, including 'int',
|
||
'float' and 'double'.
|
||
|
||
:returns: (*NDArray*) Array of zeros with the given shape and dtype.
|
||
|
||
Examples::
|
||
|
||
>>> zeros(5)
|
||
array([0.0, 0.0, 0.0, 0.0, 0.0])
|
||
>>> zeros(5, dtype='int')
|
||
array([0, 0, 0, 0, 0])
|
||
>>> zeros((2, 1))
|
||
array([[0.0]
|
||
[0.0]])
|
||
"""
|
||
shapelist = []
|
||
if isinstance(shape, int):
|
||
shapelist.append(shape)
|
||
else:
|
||
shapelist = shape
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.zeros(shapelist, dtype._dtype))
|
||
|
||
def zeros_like(a, dtype=None):
|
||
'''
|
||
Return an array of zeros with the same shape and type as a given array.
|
||
|
||
:param a: (*array*) The shape and data-type of a define these same attributes of the returned array.
|
||
:param dtype: (*string*) Overrides the data type of the result. Default is ``None``, keep the data
|
||
type of array ``a``.
|
||
|
||
:returns: Array of zeros with the same shape and type as a.
|
||
'''
|
||
shape = a.shape
|
||
if dtype is None:
|
||
dtype = _dtype.fromjava(a.dtype)
|
||
elif isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.zeros(shape, dtype._dtype))
|
||
|
||
def ones_like(a, dtype=None):
|
||
'''
|
||
Return an array of ones with the same shape and type as a given array.
|
||
|
||
:param a: (*array*) The shape and data-type of a define these same attributes of the returned array.
|
||
:param dtype: (*string*) Overrides the data type of the result. Default is ``None``, keep the data
|
||
type of array ``a``.
|
||
|
||
:returns: Array of ones with the same shape and type as a.
|
||
'''
|
||
shape = a.shape
|
||
if dtype is None:
|
||
dtype = _dtype.fromjava(a.dtype)
|
||
elif isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.ones(shape, dtype._dtype))
|
||
|
||
def ones(shape, dtype='float'):
|
||
"""
|
||
Create a new aray of given shape and type, filled with ones.
|
||
|
||
:param shape: (*int or sequence of ints*) Shape of the new array, e.g., ``(2, 3)`` or ``2``.
|
||
:param dtype: (*data-type, optional*) The desired data-type for the array, including 'int',
|
||
'float' and 'double'.
|
||
|
||
:returns: (*NDArray*) Array of ones with the given shape and dtype.
|
||
|
||
Examples::
|
||
|
||
>>> ones(5)
|
||
array([1.0, 1.0, 1.0, 1.0, 1.0])
|
||
>>> ones(5, dtype='int')
|
||
array([1, 1, 1, 1, 1])
|
||
>>> ones((2, 1))
|
||
array([[1.0]
|
||
[1.0]])
|
||
"""
|
||
shapelist = []
|
||
if isinstance(shape, int):
|
||
shapelist.append(shape)
|
||
else:
|
||
shapelist = shape
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.ones(shapelist, dtype._dtype))
|
||
|
||
def full(shape, fill_value, dtype=None):
|
||
'''
|
||
Return a new array of given shape and type, filled with fill_value.
|
||
|
||
:param shape: (*int or sequence of ints*) Shape of the new array, e.g., ``(2, 3)`` or ``2``.
|
||
:param fill_value: (*scalar*) Fill value.
|
||
:param dtype: (*data-type, optional*) The desired data-type for the array, including 'int',
|
||
'float' and 'double'.
|
||
|
||
:returns: (*NDArray*) Array of ones with the given shape and dtype.
|
||
'''
|
||
shapelist = []
|
||
if isinstance(shape, int):
|
||
shapelist.append(shape)
|
||
else:
|
||
shapelist = shape
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)._dtype
|
||
|
||
return NDArray(ArrayUtil.full(shapelist, fill_value, dtype))
|
||
|
||
def identity(n, dtype='float'):
|
||
'''
|
||
Return the identity array - a square array with ones on the main diagonal.
|
||
|
||
:param n: (*int*) Number of rows (and columns) in ``n x n`` output.
|
||
:param dtype: (*string*) The desired data-type for the array, including 'int',
|
||
'float' and 'double'. Default is ``float``.
|
||
|
||
:returns: (*NDArray*) ``n x n`` array with its main diagonal set to one, and all other elements 0.
|
||
'''
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.identity(n, dtype._dtype))
|
||
|
||
def eye(n, m=None, k=0, dtype='float'):
|
||
'''
|
||
Return a 2-D array with ones on the diagonal and zeros elsewhere.
|
||
|
||
:param n: (*int*) Number of rows in the output.
|
||
:param m: (*int*) Number of columns in the output. If ``None``, defaults to ``n``.
|
||
:param k: (*int*) Index of the diagonal: 0 (the default) refers to the main diagonal, a positive value
|
||
refers to an upper diagonal, and a negative value to a lower diagonal.
|
||
:param dtype: (*string*) The desired data-type for the array, including 'int',
|
||
'float' and 'double'. Default is ``float``.
|
||
|
||
:returns: (*NDArray*) ``n x n`` array with its main diagonal set to one, and all other elements 0.
|
||
'''
|
||
if m is None:
|
||
m = n
|
||
if isinstance(dtype, basestring):
|
||
dtype = _dtype.DataType(dtype)
|
||
return NDArray(ArrayUtil.eye(n, m, k, dtype._dtype))
|
||
|
||
def diag(v, k=0):
|
||
'''
|
||
Extract a diagonal or construct a diagonal array.
|
||
|
||
Parameters
|
||
----------
|
||
v : array_like
|
||
If `v` is a 2-D array, return a copy of its `k`-th diagonal.
|
||
If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
|
||
diagonal.
|
||
k : int, optional
|
||
Diagonal in question. The default is 0. Use `k>0` for diagonals
|
||
above the main diagonal, and `k<0` for diagonals below the main
|
||
diagonal.
|
||
|
||
Returns
|
||
-------
|
||
out : ndarray
|
||
The extracted diagonal or constructed diagonal array.
|
||
'''
|
||
if isinstance(v, (list, tuple)):
|
||
v = array(v)
|
||
return NDArray(ArrayUtil.diag(v.asarray(), k))
|
||
|
||
def repeat(a, repeats, axis=None):
|
||
'''
|
||
Repeat elements of an array.
|
||
|
||
:param repeats: (*int or list of ints*) The number of repetitions for each
|
||
element. repeats is broadcasted to fit the shape of the given axis.
|
||
:param axis: (*int*) The axis along which to repeat values. By default, use
|
||
the flattened input array, and return a flat output array.
|
||
|
||
:returns: (*array_like*) Repeated array.
|
||
'''
|
||
if isinstance(repeats, int):
|
||
repeats = [repeats]
|
||
if isinstance(a, (list, tuple)):
|
||
a = array(a)
|
||
if isinstance(a, NDArray):
|
||
a = a.asarray()
|
||
if axis is None:
|
||
r = ArrayUtil.repeat(a, repeats)
|
||
else:
|
||
r = ArrayUtil.repeat(a, repeats, axis)
|
||
return NDArray(r)
|
||
|
||
def tile(a, repeats):
|
||
'''
|
||
Construct an array by repeating ``a`` the number of times given by repeats.
|
||
|
||
If repeats has length ``d``, the result will have dimension of ``max(d, a.ndim)``.
|
||
|
||
:param repeats: (*int or list of ints*) The number of repetitions of ``a`` along each
|
||
axis.
|
||
|
||
:returns: (*array_like*) Tiled array.
|
||
'''
|
||
if isinstance(repeats, int):
|
||
repeats = [repeats]
|
||
if isinstance(a, (list, tuple)):
|
||
a = array(a)
|
||
if isinstance(a, NDArray):
|
||
a = a.asarray()
|
||
r = ArrayUtil.tile(a, repeats)
|
||
return NDArray(r)
|
||
|
||
def rand(*args):
|
||
"""
|
||
Random values in a given shape.
|
||
|
||
Create an array of the given shape and propagate it with random samples from a uniform
|
||
distribution over [0, 1).
|
||
|
||
:param d0, d1, ..., dn: (*int*) optional. The dimensions of the returned array, should all
|
||
be positive. If no argument is given a single Python float is returned.
|
||
|
||
:returns: Random values array.
|
||
"""
|
||
if len(args) == 0:
|
||
return ArrayUtil.rand()
|
||
elif len(args) == 1:
|
||
return NDArray(ArrayUtil.rand(args[0]))
|
||
else:
|
||
return NDArray(ArrayUtil.rand(args))
|
||
|
||
def absolute(x):
|
||
'''
|
||
Calculate the absolute value element-wise.
|
||
|
||
:param x: (*array_like*) Input array.
|
||
|
||
:returns: An array containing the absolute value of each element in x.
|
||
For complex input, a + ib, the absolute value is \sqrt{ a^2 + b^2 }.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if isinstance(x, NDArray):
|
||
return x.abs()
|
||
else:
|
||
return abs(x)
|
||
|
||
def ceil(x):
|
||
'''
|
||
Return the ceiling of the input, element-wise.
|
||
|
||
:param x: (*array_like*) Input array.
|
||
|
||
:return: The ceiling of each element.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if isinstance(x, NDArray):
|
||
return x.ceil()
|
||
else:
|
||
return math.ceil(x)
|
||
|
||
def floor(x):
|
||
'''
|
||
Return the floor of the input, element-wise.
|
||
|
||
:param x: (*array_like*) Input array.
|
||
|
||
:return: The floor of each element.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if isinstance(x, NDArray):
|
||
return x.floor()
|
||
else:
|
||
return math.floor(x)
|
||
|
||
def square(x):
|
||
"""
|
||
Return the element-wise square of the input.
|
||
|
||
:param x: (*array_like*) Input data.
|
||
|
||
:returns: Element-wise x*x, of the same shape and dtype as x. This is a scalar if x is a scalar.
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).square()
|
||
elif isinstance(x, NDArray):
|
||
return x.square()
|
||
else:
|
||
return x * x
|
||
|
||
def sqrt(x):
|
||
"""
|
||
Return the positive square-root of an array, element-wise.
|
||
|
||
:param x: (*array_like*) The values whose square-roots are required.
|
||
|
||
:returns: (*array_like*) An array of the same shape as *x*, containing the positive
|
||
square-root of each element in *x*.
|
||
|
||
Examples::
|
||
|
||
>>> sqrt([1,4,9])
|
||
array([1.0, 2.0, 3.0])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).sqrt()
|
||
elif isinstance(x, NDArray):
|
||
return x.sqrt()
|
||
else:
|
||
return math.sqrt(x)
|
||
|
||
def power(x1, x2):
|
||
"""
|
||
First array elements raised to powers from second array, element-wise.
|
||
|
||
:param x1: (*array_like*) The bases.
|
||
:param x2: (*array_like*) The exponents.
|
||
|
||
:returns: (*array_like*) The bases in *x1* raised to the exponents in *x2*.
|
||
"""
|
||
if isinstance(x1, list):
|
||
x1 = array(x1)
|
||
if isinstance(x2, list):
|
||
x2 = array(x2)
|
||
if isinstance(x1, NDArray):
|
||
if isinstance(x2, NDArray):
|
||
return NDArray(ArrayMath.pow(x1.asarray(), x2.asarray()))
|
||
else:
|
||
return NDArray(ArrayMath.pow(x1.asarray(), x2))
|
||
else:
|
||
if isinstance(x2, NDArray):
|
||
return NDArray(ArrayMath.pow(x1, x2.asarray()))
|
||
else:
|
||
if isinstance(x1, complex):
|
||
return pow(x1, x2)
|
||
else:
|
||
return math.pow(x1, x2)
|
||
|
||
def degrees(x):
|
||
'''
|
||
Convert radians to degrees.
|
||
|
||
:param x: (*array_like*) Array in radians.
|
||
|
||
:returns: (*array_like*) Array in degrees.
|
||
'''
|
||
if isinstance(x, (list, tuple)):
|
||
x = array(x)
|
||
if isinstance(x, NDArray):
|
||
return NDArray(ArrayMath.toDegrees(x.asarray()))
|
||
else:
|
||
return math.degrees(x)
|
||
|
||
def radians(x):
|
||
'''
|
||
Convert degrees to radians.
|
||
|
||
:param x: (*array_like*) Array in degrees.
|
||
|
||
:returns: (*array_like*) Array in radians.
|
||
'''
|
||
if isinstance(x, (list, tuple)):
|
||
x = array(x)
|
||
if isinstance(x, NDArray):
|
||
return NDArray(ArrayMath.toRadians(x.asarray()))
|
||
else:
|
||
return math.radians(x)
|
||
|
||
def sin(x):
|
||
"""
|
||
Trigonometric sine, element-wise.
|
||
|
||
:param x: (*array_like*) Angle, in radians.
|
||
|
||
:returns: (*array_like*) The sine of each element of x.
|
||
|
||
Examples::
|
||
|
||
>>> sin(pi/2.)
|
||
1.0
|
||
>>> sin(array([0., 30., 45., 60., 90.]) * pi / 180)
|
||
array([0.0, 0.49999999999999994, 0.7071067811865475, 0.8660254037844386, 1.0])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).sin()
|
||
elif isinstance(x, NDArray):
|
||
return x.sin()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.sin(x)
|
||
else:
|
||
return math.sin(x)
|
||
|
||
def cos(x):
|
||
"""
|
||
Trigonometric cosine, element-wise.
|
||
|
||
:param x: (*array_like*) Angle, in radians.
|
||
|
||
:returns: (*array_like*) The cosine of each element of x.
|
||
|
||
Examples::
|
||
|
||
>>> cos(array([0, pi/2, pi]))
|
||
array([1.0, 6.123233995736766E-17, -1.0])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).cos()
|
||
elif isinstance(x, NDArray):
|
||
return x.cos()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.cos(x)
|
||
else:
|
||
return math.cos(x)
|
||
|
||
def tan(x):
|
||
"""
|
||
Trigonometric tangent, element-wise.
|
||
|
||
:param x: (*array_like*) Angle, in radians.
|
||
|
||
:returns: (*array_like*) The tangent of each element of x.
|
||
|
||
Examples::
|
||
|
||
>>> tan(array([-pi,pi/2,pi]))
|
||
array([1.2246467991473532E-16, 1.633123935319537E16, -1.2246467991473532E-16])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).tan()
|
||
elif isinstance(x, NDArray):
|
||
return x.tan()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.tan(x)
|
||
else:
|
||
return math.tan(x)
|
||
|
||
def asin(x):
|
||
"""
|
||
Trigonometric inverse sine, element-wise.
|
||
|
||
:param x: (*array_like*) *x*-coordinate on the unit circle.
|
||
|
||
:returns: (*array_like*) The inverse sine of each element of *x*, in radians and in the
|
||
closed interval ``[-pi/2, pi/2]``.
|
||
|
||
Examples::
|
||
|
||
>>> asin(array([1,-1,0]))
|
||
array([1.5707964, -1.5707964, 0.0])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).asin()
|
||
elif isinstance(x, NDArray):
|
||
return x.asin()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.asin(x)
|
||
else:
|
||
return math.asin(x)
|
||
|
||
def acos(x):
|
||
"""
|
||
Trigonometric inverse cosine, element-wise.
|
||
|
||
:param x: (*array_like*) *x*-coordinate on the unit circle. For real arguments, the domain
|
||
is ``[-1, 1]``.
|
||
|
||
:returns: (*array_like*) The inverse cosine of each element of *x*, in radians and in the
|
||
closed interval ``[0, pi]``.
|
||
|
||
Examples::
|
||
|
||
>>> acos([1, -1])
|
||
array([0.0, 3.1415927])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).acos()
|
||
elif isinstance(x, NDArray):
|
||
return x.acos()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.acos(x)
|
||
else:
|
||
return math.acos(x)
|
||
|
||
def atan(x):
|
||
"""
|
||
Trigonometric inverse tangent, element-wise.
|
||
|
||
The inverse of tan, so that if ``y = tan(x)`` then ``x = atan(y)``.
|
||
|
||
:param x: (*array_like*) Input values, ``atan`` is applied to each element of *x*.
|
||
|
||
:returns: (*array_like*) Out has the same shape as *x*. Its real part is in
|
||
``[-pi/2, pi/2]`` .
|
||
|
||
Examples::
|
||
|
||
>>> atan([0, 1])
|
||
array([0.0, 0.7853982])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).atan()
|
||
elif isinstance(x, NDArray):
|
||
return x.atan()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.atan(x)
|
||
else:
|
||
return math.atan(x)
|
||
|
||
def atan2(x1, x2):
|
||
"""
|
||
Element-wise arc tangent of ``x1/x2`` choosing the quadrant correctly.
|
||
|
||
:param x1: (*array_like*) *y*-coordinates.
|
||
:param x2: (*array_like*) *x*-coordinates. *x2* must be broadcastable to match the
|
||
shape of *x1* or vice versa.
|
||
|
||
:returns: (*array_like*) Array of angles in radians, in the range ``[-pi, pi]`` .
|
||
|
||
Examples::
|
||
|
||
>>> x = array([-1, +1, +1, -1])
|
||
>>> y = array([-1, -1, +1, +1])
|
||
>>> atan2(y, x) * 180 / pi
|
||
array([-135.00000398439022, -45.000001328130075, 45.000001328130075, 135.00000398439022])
|
||
"""
|
||
if isinstance(x1, NDArray):
|
||
r = NDArray(ArrayMath.atan2(x1._array, x2._array))
|
||
if isinstance(x1, DimArray):
|
||
return DimArray(r, x1.dims, x1.fill_value, x1.proj)
|
||
else:
|
||
return r
|
||
else:
|
||
return math.atan2(x1, x2)
|
||
|
||
def exp(x):
|
||
"""
|
||
Calculate the exponential of all elements in the input array.
|
||
|
||
:param x: (*array_like*) Input values.
|
||
|
||
:returns: (*array_like*) Output array, element-wise exponential of *x* .
|
||
|
||
Examples::
|
||
|
||
>>> x = linspace(-2*pi, 2*pi, 10)
|
||
>>> exp(x)
|
||
array([0.0018674424051939472, 0.007544609964764651, 0.030480793298392952,
|
||
0.12314470389303135, 0.4975139510383202, 2.0099938864286777,
|
||
8.120527869949177, 32.80754507307142, 132.54495655444984, 535.4917491531113])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).exp()
|
||
elif isinstance(x, NDArray):
|
||
return x.exp()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.exp(x)
|
||
else:
|
||
return math.exp(x)
|
||
|
||
def log(x):
|
||
"""
|
||
Natural logarithm, element-wise.
|
||
|
||
The natural logarithm log is the inverse of the exponential function, so that
|
||
*log(exp(x))* = *x* . The natural logarithm is logarithm in base e.
|
||
|
||
:param x: (*array_like*) Input values.
|
||
|
||
:returns: (*array_like*) The natural logarithm of *x* , element-wise.
|
||
|
||
Examples::
|
||
|
||
>>> log([1, e, e**2, 0])
|
||
array([0.0, 1.0, 2.0, -Infinity])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).log()
|
||
elif isinstance(x, NDArray):
|
||
return x.log()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.exp(x)
|
||
else:
|
||
return math.log(x)
|
||
|
||
def log10(x):
|
||
"""
|
||
Return the base 10 logarithm of the input array, element-wise.
|
||
|
||
:param x: (*array_like*) Input values.
|
||
|
||
:returns: (*array_like*) The logarithm to the base 10 of *x* , element-wise.
|
||
|
||
Examples::
|
||
|
||
>>> log10([1e-15, -3.])
|
||
array([-15., NaN])
|
||
"""
|
||
if isinstance(x, list):
|
||
return array(x).log10()
|
||
elif isinstance(x, NDArray):
|
||
return x.log10()
|
||
else:
|
||
if isinstance(x, complex):
|
||
return cmath.log10(x)
|
||
else:
|
||
return math.log10(x)
|
||
|
||
def sign(x):
|
||
'''
|
||
Returns an element-wise indication of the sign of a number.
|
||
|
||
The sign function returns -1 if x < 0, 0 if x==0, 1 if x > 0. nan is returned for nan inputs.
|
||
|
||
:param x: (*array_like*) Input values.
|
||
|
||
:returns: The sign of x. This is a scalar if x is a scalar.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
|
||
if isinstance(x, NDArray):
|
||
return x.sign()
|
||
else:
|
||
return math.copysign(1, x)
|
||
|
||
def any(x, axis=None):
|
||
'''
|
||
Test whether any array element along a given axis evaluates to True.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which a logical OR reduction is performed.
|
||
The default (axis = None) is to perform a logical OR over all the
|
||
dimensions of the input array.
|
||
|
||
:returns: (*array_like*) Any result
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
|
||
if axis is None:
|
||
return ArrayMath.any(x._array)
|
||
else:
|
||
if axis < 0:
|
||
axis += x.ndim
|
||
return NDArray(ArrayMath.any(x._array, axis))
|
||
|
||
def all(x, axis=None):
|
||
'''
|
||
Test whether all array element along a given axis evaluates to True.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which a logical OR reduction is performed.
|
||
The default (axis = None) is to perform a logical OR over all the
|
||
dimensions of the input array.
|
||
|
||
:returns: (*array_like*) All result
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
|
||
if axis is None:
|
||
return ArrayMath.all(x._array)
|
||
else:
|
||
if axis < 0:
|
||
axis += x.ndim
|
||
return NDArray(ArrayMath.all(x._array, axis))
|
||
|
||
def sum(x, axis=None):
|
||
"""
|
||
Sum of array elements over a given axis.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which the standard deviation is computed.
|
||
The default is to compute the standard deviation of the flattened array.
|
||
|
||
:returns: (*array_like*) Sum result
|
||
"""
|
||
if isinstance(x, list):
|
||
if isinstance(x[0], NDArray):
|
||
a = []
|
||
for xx in x:
|
||
a.append(xx.asarray())
|
||
r = ArrayMath.sum(a)
|
||
if type(x[0]) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
return DimArray(NDArray(r), x[0].dims, x[0].fill_value, x[0].proj)
|
||
else:
|
||
x = array(x)
|
||
if axis is None:
|
||
r = ArrayMath.sum(x.asarray())
|
||
return r
|
||
else:
|
||
r = ArrayMath.sum(x.asarray(), axis)
|
||
if type(x) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
dims = []
|
||
for i in range(0, x.ndim):
|
||
if i != axis:
|
||
dims.append(x.dims[i])
|
||
return DimArray(NDArray(r), dims, x.fill_value, x.proj)
|
||
|
||
def cumsum(x, axis=None):
|
||
"""
|
||
Return the cumulative sum of the elements along a given axis.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which the standard deviation is computed.
|
||
The default is to compute the standard deviation of the flattened array.
|
||
|
||
:returns: (*array_like*) Cumulative sum result.
|
||
"""
|
||
x = asarray(x)
|
||
if axis is None:
|
||
x = x.flatten()
|
||
axis = 0
|
||
|
||
r = ArrayMath.cumsum(x.asarray(), axis)
|
||
if type(x) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
dims = []
|
||
for i in range(0, x.ndim):
|
||
dims.append(x.dims[i])
|
||
return DimArray(NDArray(r), dims, x.fill_value, x.proj)
|
||
|
||
def mean(x, axis=None):
|
||
"""
|
||
Compute tha arithmetic mean along the specified axis.
|
||
|
||
:param x: (*array_like*) Input values.
|
||
:param axis: (*int*) Axis along which the standard deviation is computed.
|
||
The default is to compute the standard deviation of the flattened array.
|
||
|
||
returns: (*array_like*) Mean result
|
||
"""
|
||
if isinstance(x, list):
|
||
if isinstance(x[0], NDArray):
|
||
a = []
|
||
for xx in x:
|
||
a.append(xx.asarray())
|
||
r = ArrayMath.mean(a)
|
||
if type(x[0]) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
return DimArray(NDArray(r), x[0].dims, x[0].fill_value, x[0].proj)
|
||
elif isinstance(x[0], PyStationData):
|
||
a = []
|
||
for xx in x:
|
||
a.append(xx.data)
|
||
r = DataMath.mean(a)
|
||
return PyStationData(r)
|
||
else:
|
||
x = array(x)
|
||
r = x.mean(axis)
|
||
return r
|
||
|
||
def average(a, axis=None, weights=None):
|
||
"""
|
||
Compute tha arithmetic mean along the specified axis.
|
||
|
||
:param a: (*array_like*) Input values.
|
||
:param axis: (*int*) Axis along which the standard deviation is computed.
|
||
The default is to compute the standard deviation of the flattened array.
|
||
:param weights: (*array_like*) An array of weights associated with the values in `a`. Each value in
|
||
`a` contributes to the average according to its associated weight.
|
||
|
||
returns: (*array_like*) Average result
|
||
"""
|
||
a = asanyarray(a)
|
||
|
||
if weights is None:
|
||
return a.mean(axis)
|
||
else:
|
||
wgt = asanyarray(weights)
|
||
# Sanity checks
|
||
if a.shape != wgt.shape:
|
||
if axis is None:
|
||
raise TypeError(
|
||
"Axis must be specified when shapes of a and weights "
|
||
"differ.")
|
||
if wgt.ndim != 1:
|
||
raise TypeError(
|
||
"1D weights expected when shapes of a and weights differ.")
|
||
if wgt.shape[0] != a.shape[axis]:
|
||
raise ValueError(
|
||
"Length of weights not compatible with specified axis.")
|
||
|
||
# setup wgt to broadcast along axis
|
||
wgt = broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape)
|
||
wgt = wgt.swapaxes(-1, axis)
|
||
|
||
scl = wgt.sum(axis=axis)
|
||
avg = (a * wgt).sum(axis) / scl
|
||
|
||
if type(a) is NDArray:
|
||
return avg
|
||
else:
|
||
dims = []
|
||
for i in range(0, a.ndim):
|
||
if i != axis:
|
||
dims.append(a.dims[i])
|
||
return DimArray(avg, dims, x.fill_value, x.proj)
|
||
|
||
def std(x, axis=None, ddof=0):
|
||
'''
|
||
Compute the standard deviation along the specified axis.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which the standard deviation is computed.
|
||
The default is to compute the standard deviation of the flattened array.
|
||
:param ddof: (*int*) Delta Degrees of Freedom: the divisor used in the calculation is
|
||
N - ddof, where N represents the number of elements. By default ddof is zero.
|
||
|
||
returns: (*array_like*) Standart deviation result.
|
||
'''
|
||
if isinstance(x, (list, tuple)):
|
||
x = array(x)
|
||
r = x.std(axis, ddof)
|
||
return r
|
||
|
||
def var(x, axis=None, ddof=0):
|
||
'''
|
||
Compute variance along the specified axis.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which the variance is computed.
|
||
The default is to compute the variance of the flattened array.
|
||
:param ddof: (*int*) Delta Degrees of Freedom: the divisor used in the calculation is
|
||
N - ddof, where N represents the number of elements. By default ddof is zero.
|
||
|
||
returns: (*array_like*) Variance result.
|
||
'''
|
||
if isinstance(x, (list, tuple)):
|
||
x = array(x)
|
||
r = x.var(axis, ddof)
|
||
return r
|
||
|
||
def median(x, axis=None):
|
||
"""
|
||
Compute tha median along the specified axis.
|
||
|
||
:param x: (*array_like or list*) Input values.
|
||
:param axis: (*int*) Axis along which the standard deviation is computed.
|
||
The default is to compute the standard deviation of the flattened array.
|
||
|
||
returns: (*array_like*) Median result
|
||
"""
|
||
if isinstance(x, list):
|
||
if isinstance(x[0], NDArray):
|
||
a = []
|
||
for xx in x:
|
||
a.append(xx.asarray())
|
||
r = ArrayMath.median(a)
|
||
if type(x[0]) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
return DimArray(NDArray(r), x[0].dims, x[0].fill_value, x[0].proj)
|
||
elif isinstance(x[0], PyStationData):
|
||
a = []
|
||
for xx in x:
|
||
a.append(xx.data)
|
||
r = DataMath.median(a)
|
||
return PyStationData(r)
|
||
else:
|
||
x = array(x)
|
||
r = x.median(axis)
|
||
return r
|
||
|
||
def maximum(x1, x2):
|
||
"""
|
||
Element-wise maximum of array elements.
|
||
|
||
Compare two arrays and returns a new array containing the element-wise maxima. If one of the elements
|
||
being compared is a NaN, then that element is returned. If both elements are NaNs then the first is
|
||
returned. The latter distinction is important for complex NaNs, which are defined as at least one of
|
||
the real or imaginary parts being a NaN. The net effect is that NaNs are propagated.
|
||
|
||
:param x1,x2: (*array_like*) The arrays holding the elements to be compared. They must have the same
|
||
shape.
|
||
|
||
:returns: The maximum of x1 and x2, element-wise. Returns scalar if both x1 and x2 are scalars.
|
||
"""
|
||
if isinstance(x1, list):
|
||
x1 = array(x1)
|
||
if isinstance(x2, list):
|
||
x2 = array(x2)
|
||
if type(x1) is NDArray:
|
||
return NDArray(ArrayMath.maximum(x1.asarray(), x2.asarray()))
|
||
elif isinstance(x1, DimArray):
|
||
r = NDArray(ArrayMath.maximum(x1.asarray(), x2.asarray()))
|
||
return DimArray(r, x1.dims, x1.fill_value, x1.proj)
|
||
else:
|
||
return max(x1, x2)
|
||
|
||
def fmax(x1, x2):
|
||
"""
|
||
Element-wise maximum of array elements.
|
||
|
||
Compare two arrays and returns a new array containing the element-wise maxima. If one of the
|
||
elements being compared is a NaN, then the non-nan element is returned. If both elements are
|
||
NaNs then the first is returned. The latter distinction is important for complex NaNs, which
|
||
are defined as at least one of the real or imaginary parts being a NaN. The net effect is that
|
||
NaNs are ignored when possible.
|
||
|
||
:param x1,x2: (*array_like*) The arrays holding the elements to be compared. They must have the same
|
||
shape.
|
||
|
||
:returns: The maximum of x1 and x2, element-wise. Returns scalar if both x1 and x2 are scalars.
|
||
"""
|
||
if isinstance(x1, list):
|
||
x1 = array(x1)
|
||
if isinstance(x2, list):
|
||
x2 = array(x2)
|
||
if type(x1) is NDArray:
|
||
return NDArray(ArrayMath.fmax(x1.asarray(), x2.asarray()))
|
||
elif isinstance(x1, DimArray):
|
||
r = NDArray(ArrayMath.fmax(x1.asarray(), x2.asarray()))
|
||
return DimArray(r, x1.dims, x1.fill_value, x1.proj)
|
||
else:
|
||
return max(x1, x2)
|
||
|
||
def minimum(x1, x2):
|
||
"""
|
||
Element-wise minimum of array elements.
|
||
|
||
Compare two arrays and returns a new array containing the element-wise minima. If one of the elements
|
||
being compared is a NaN, then that element is returned. If both elements are NaNs then the first is
|
||
returned. The latter distinction is important for complex NaNs, which are defined as at least one of
|
||
the real or imaginary parts being a NaN. The net effect is that NaNs are propagated.
|
||
|
||
:param x1,x2: (*array_like*) The arrays holding the elements to be compared. They must have the same
|
||
shape.
|
||
|
||
:returns: The minimum of x1 and x2, element-wise. Returns scalar if both x1 and x2 are scalars.
|
||
"""
|
||
if isinstance(x1, list):
|
||
x1 = array(x1)
|
||
if isinstance(x2, list):
|
||
x2 = array(x2)
|
||
if type(x1) is NDArray:
|
||
return NDArray(ArrayMath.minimum(x1.asarray(), x2.asarray()))
|
||
elif isinstance(x1, DimArray):
|
||
r = NDArray(ArrayMath.minimum(x1.asarray(), x2.asarray()))
|
||
return DimArray(r, x1.dims, x1.fill_value, x1.proj)
|
||
else:
|
||
return min(x1, x2)
|
||
|
||
def fmin(x1, x2):
|
||
"""
|
||
Element-wise minimum of array elements.
|
||
|
||
Compare two arrays and returns a new array containing the element-wise minima. If one of the
|
||
elements being compared is a NaN, then the non-nan element is returned. If both elements are
|
||
NaNs then the first is returned. The latter distinction is important for complex NaNs, which
|
||
are defined as at least one of the real or imaginary parts being a NaN. The net effect is that
|
||
NaNs are ignored when possible.
|
||
|
||
:param x1,x2: (*array_like*) The arrays holding the elements to be compared. They must have the same
|
||
shape.
|
||
|
||
:returns: The minimum of x1 and x2, element-wise. Returns scalar if both x1 and x2 are scalars.
|
||
"""
|
||
if isinstance(x1, list):
|
||
x1 = array(x1)
|
||
if isinstance(x2, list):
|
||
x2 = array(x2)
|
||
if type(x1) is NDArray:
|
||
return NDArray(ArrayMath.fmin(x1.asarray(), x2.asarray()))
|
||
elif isinstance(x1, DimArray):
|
||
r = NDArray(ArrayMath.fmin(x1.asarray(), x2.asarray()))
|
||
return DimArray(r, x1.dims, x1.fill_value, x1.proj)
|
||
else:
|
||
return min(x1, x2)
|
||
|
||
def min(a, axis=None):
|
||
'''
|
||
Returns the minimum values along an axis.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
:param axis: (*int*) By default, the minimum is into the flattened array, otherwise
|
||
along the specified axis.
|
||
|
||
:returns: Array of minimum values. It has the same shape as a.shape with the
|
||
dimension along axis removed.
|
||
'''
|
||
if isinstance(a, (list, tuple)):
|
||
a = array(a)
|
||
return a.min(axis)
|
||
|
||
def max(a, axis=None):
|
||
'''
|
||
Returns the maximum values along an axis.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
:param axis: (*int*) By default, the maximum is into the flattened array, otherwise
|
||
along the specified axis.
|
||
|
||
:returns: Array of maximum values. It has the same shape as a.shape with the
|
||
dimension along axis removed.
|
||
'''
|
||
if isinstance(a, (list, tuple)):
|
||
a = array(a)
|
||
return a.max(axis)
|
||
|
||
def argmin(a, axis=None):
|
||
'''
|
||
Returns the indices of the minimum values along an axis.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
:param axis: (*int*) By default, the index is into the flattened array, otherwise
|
||
along the specified axis.
|
||
|
||
:returns: Array of indices into the array. It has the same shape as a.shape with the
|
||
dimension along axis removed.
|
||
'''
|
||
if axis is None:
|
||
r = ArrayMath.argMin(a.asarray())
|
||
return r
|
||
else:
|
||
r = ArrayMath.argMin(a.asarray(), axis)
|
||
return NDArray(r)
|
||
|
||
def argmax(a, axis=None):
|
||
'''
|
||
Returns the indices of the minimum values along an axis.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
:param axis: (*int*) By default, the index is into the flattened array, otherwise
|
||
along the specified axis.
|
||
|
||
:returns: Array of indices into the array. It has the same shape as a.shape with the
|
||
dimension along axis removed.
|
||
'''
|
||
if axis is None:
|
||
r = ArrayMath.argMax(a.asarray())
|
||
return r
|
||
else:
|
||
r = ArrayMath.argMax(a.asarray(), axis)
|
||
return NDArray(r)
|
||
|
||
def diff(a, axis=-1):
|
||
'''
|
||
Calculate the n-th discrete difference along the given axis.
|
||
|
||
The first difference is given by out[n] = a[n+1] - a[n] along the given axis.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
:param axis: (*int*) The axis along which the difference is taken, default is the last axis.
|
||
|
||
:returns: The n-th differences. The shape of the output is the same as a except along axis
|
||
where the dimension is smaller by n.
|
||
'''
|
||
a = asarray(a)
|
||
nd = a.ndim
|
||
if axis < 0:
|
||
axis = nd + axis
|
||
|
||
slice1 = [slice(None)] * nd
|
||
slice2 = [slice(None)] * nd
|
||
slice1[axis] = slice(1, None)
|
||
slice2[axis] = slice(None, -1)
|
||
slice1 = tuple(slice1)
|
||
slice2 = tuple(slice2)
|
||
r = a[slice1] - a[slice2]
|
||
return r
|
||
|
||
def unravel_index(indices, dims):
|
||
'''
|
||
Converts a flat index or array of flat indices into a tuple of coordinate arrays.
|
||
|
||
:param indices: (*array_like*) An integer array whose elements are indices into the
|
||
flattened version of an array of dimensions ``dims``.
|
||
:param dims: (*tuple of ints*) The shape of the array to use for unraveling indices.
|
||
|
||
:returns: tuple of ndarray. Each array in the tuple has the same shape as the indices
|
||
array.
|
||
'''
|
||
if isinstance(indices, int):
|
||
idx = indices
|
||
coords = []
|
||
for i in range(len(dims)):
|
||
if i < len(dims) - 1:
|
||
n = 1
|
||
for j in range(i + 1, len(dims)):
|
||
n = n * dims[j]
|
||
coord = idx / n
|
||
coords.append(coord)
|
||
idx = idx - coord * n
|
||
else:
|
||
coords.append(idx)
|
||
return tuple(coords)
|
||
|
||
def ave_month(data, colnames, t):
|
||
"""
|
||
Average data month by month.
|
||
|
||
:param data: (*list of Array*) Data array list.
|
||
:param colnames: (*list of string*) Column name list.
|
||
:param t: (*list of datetime*) Datetime list.
|
||
|
||
:returns: (*PyTableData*) Averaged table data.
|
||
"""
|
||
jt = miutil.jdate(t)
|
||
if isinstance(data, NDArray):
|
||
a = [data.asarray()]
|
||
else:
|
||
a = []
|
||
for d in data:
|
||
a.append(d.asarray())
|
||
r = TableUtil.ave_Month(a, colnames, jt)
|
||
return PyTableData(TableData(r))
|
||
|
||
def histogram(a, bins=10, density=False):
|
||
'''
|
||
Compute the histogram of a set of data.
|
||
|
||
:param a: (*array_like*) Input data. The histogram is computed over the flattened array.
|
||
:param bins: (*int or list*) If bins is an int, it defines the number of equal-width bins in the given
|
||
range (10, by default). If bins is a sequence, it defines the bin edges, including the rightmost edge, allowing for non-uniform bin widths.
|
||
:param density: (*boolean*) If False, the result will contain the number of samples in
|
||
each bin. If True, the result is the value of the probability density function at
|
||
the bin, normalized such that the integral over the range is 1.
|
||
|
||
:returns: The values of the histogram (hist) and the bin edges (length(hist)+1).
|
||
'''
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
elif isinstance(a, numbers.Number):
|
||
a = array([a])
|
||
if isinstance(bins, list):
|
||
bins = array(bins)
|
||
if isinstance(bins, int):
|
||
r = ArrayUtil.histogram(a.asarray(), bins)
|
||
else:
|
||
r = ArrayUtil.histogram(a.asarray(), bins.asarray())
|
||
h = NDArray(r[0])
|
||
b = NDArray(r[1])
|
||
|
||
if density:
|
||
db = diff(b).astype('float')
|
||
return h / db / h.sum(), b
|
||
else:
|
||
return h, b
|
||
|
||
def sort(a, axis=-1):
|
||
"""
|
||
Returns the indices that would sort an array.
|
||
|
||
:param a: (*array_like*) Array to be sorted.
|
||
:param axis: (*int or None*) Optional. Axis along which to sort. If None, the array is
|
||
flattened after sorting. The default is ``-1`` , which sorts along the last axis.
|
||
|
||
:returns: (*NDArray*) Sorted array.
|
||
"""
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
r = ArrayUtil.sort(a.asarray(), axis)
|
||
return NDArray(r)
|
||
|
||
def argsort(a, axis=-1):
|
||
"""
|
||
Return a sorted copy of an array.
|
||
|
||
:param a: (*array_like*) Array to be sorted.
|
||
:param axis: (*int or None*) Optional. Axis along which to sort. If None, the array is
|
||
flattened after sorting. The default is ``-1`` , which sorts along the last axis.
|
||
|
||
:returns: (*NDArray*) Array of indices that sort a along the specified axis. If a is
|
||
one-dimensional, a[index_array] yields a sorted a.
|
||
"""
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
r = ArrayUtil.argSort(a.asarray(), axis)
|
||
return NDArray(r)
|
||
|
||
def unique(a, axis=None):
|
||
"""
|
||
Find the unique elements of an array.
|
||
|
||
Returns the sorted unique elements of an array.
|
||
|
||
:param a: (*array_like*) Array to be sorted.
|
||
:param axis: (*int or None*) Optional. Axis along which to operate on. If None, the array is
|
||
flattened.
|
||
|
||
:returns: (*NDArray*) Sorted unique elements of input array.
|
||
"""
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
r = ArrayUtil.unique(a.asarray(), axis)
|
||
return NDArray(r)
|
||
|
||
def isnan(a):
|
||
'''
|
||
Test element-wise for NaN and return result as a boolean array.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
|
||
:returns: (*array*) For scalar input, the result is a new boolean with value True if the input is NaN;
|
||
otherwise the value is False. For array input, the result is a boolean array of the same dimensions
|
||
as the input and the values are True if the corresponding element of the input is NaN; otherwise the
|
||
values are False.
|
||
'''
|
||
if isinstance(a, (list, tuple)):
|
||
a = array(a)
|
||
if isarray(a):
|
||
return a == nan
|
||
else:
|
||
return Double.isNaN(a)
|
||
|
||
def isinf(x):
|
||
'''
|
||
Test element-wise for positive or negative infinity.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
|
||
:returns: (*array*) True where x is positive or negative infinity, false otherwise. This is a scalar if x
|
||
is a scalar.
|
||
'''
|
||
if isinstance(x, (list, tuple)):
|
||
x = array(x)
|
||
if isarray(x):
|
||
return ArrayMath.isInfinite(x._array)
|
||
else:
|
||
return Double.isInfinite(a)
|
||
|
||
def isfinite(x):
|
||
'''
|
||
Test element-wise for finiteness (not infinity or not Not a Number).
|
||
|
||
:param a: (*array_like*) Input array.
|
||
|
||
:returns: (*array*) True where x is not positive infinity, negative infinity, or NaN; false otherwise. This is a
|
||
scalar if x is a scalar.
|
||
'''
|
||
if isinstance(x, (list, tuple)):
|
||
x = array(x)
|
||
if isarray(x):
|
||
return ArrayMath.isFinite(x._array)
|
||
else:
|
||
return Double.isFinite(a)
|
||
|
||
def delnan(a):
|
||
'''
|
||
Delete NaN values.
|
||
|
||
:param a: (*arrays*) Input arrays with one dimension.
|
||
|
||
:returns: The array or arrays without NaN values.
|
||
'''
|
||
if isinstance(a, (list, tuple))and (not isinstance(a[0], NDArray)):
|
||
a = array(a)
|
||
if isinstance(a, NDArray):
|
||
r = ArrayMath.removeNaN(a._array)[0]
|
||
return NDArray(r)
|
||
else:
|
||
aa = []
|
||
for a0 in a:
|
||
aa.append(a0._array)
|
||
r = ArrayMath.removeNaN(aa)
|
||
rr = []
|
||
for r1 in r:
|
||
rr.append(NDArray(r1))
|
||
return rr
|
||
|
||
def nonzero(a):
|
||
'''
|
||
Return the indices of the elements that are non-zero.
|
||
|
||
Returns a tuple of arrays, one for each dimension of a, containing the indices of the
|
||
non-zero elements in that dimension.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
|
||
:returns: (*tuple*) Indices of elements that are non-zero.
|
||
'''
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
ra = ArrayMath.nonzero(a.asarray())
|
||
if ra is None:
|
||
return None
|
||
|
||
r = []
|
||
for aa in ra:
|
||
r.append(NDArray(aa))
|
||
return tuple(r)
|
||
|
||
def where(condition):
|
||
'''
|
||
Return elements, either from x or y, depending on condition.
|
||
|
||
If only condition is given, return condition.nonzero().
|
||
|
||
:param condition: (*array_like*) Input array.
|
||
|
||
:returns: (*tuple*) Indices of elements that are non-zero.
|
||
'''
|
||
return nonzero(condition)
|
||
|
||
def logical_not(arr):
|
||
'''
|
||
Compute the truth value of NOT x element-wise.
|
||
|
||
:param arr: (*array_like*) Input array.
|
||
:return: (*array_like*) Boolean result with the same shape as x of the NOT operation on elements of x.
|
||
This is a scalar if x is a scalar.
|
||
'''
|
||
if isinstance(arr, int):
|
||
return arr == 0
|
||
elif isinstance(arr, bool):
|
||
return not arr
|
||
|
||
if isinstance(arr, (list, tuple)):
|
||
arr = array(arr)
|
||
r = ArrayMath.logicalNot(arr._array)
|
||
return NDArray(r)
|
||
|
||
def delete(arr, obj, axis=None):
|
||
'''
|
||
Return a new array with sub-arrays along an axis deleted.
|
||
|
||
:param arr: (*array_like*) Input array.
|
||
:param obj: (*slice, int or array of ints*) Indicate which sub-arrays to remove.
|
||
:param axis: (*int*) The axis along which to delete the subarray defined by obj.
|
||
If axis is None, obj is applied to the flattened array.
|
||
|
||
:returns: A copy of arr with the elements specified by obj removed. If axis is None,
|
||
out is a flattened array.
|
||
'''
|
||
if isinstance(arr, (list, tuple)):
|
||
arr = array(arr)
|
||
|
||
if isinstance(obj, NDArray):
|
||
obj = obj.aslist()
|
||
|
||
if axis is None:
|
||
arr = arr.reshape(arr.size)
|
||
axis = 0
|
||
|
||
r = ArrayUtil.delete(arr._array, obj, axis)
|
||
return NDArray(r)
|
||
|
||
def concatenate(arrays, axis=0):
|
||
'''
|
||
Join a sequence of arrays along an existing axis.
|
||
|
||
:param arrays: (list of arrays) The arrays must have the same shape, except in the dimension
|
||
corresponding to axis (the first, by default).
|
||
:param axis: (*int*) The axis along which the arrays will be joined. Default is 0.
|
||
|
||
:returns: (*array_like*) The concatenated array.
|
||
'''
|
||
ars = []
|
||
for a in arrays:
|
||
ars.append(a.asarray())
|
||
r = ArrayUtil.concatenate(ars, axis)
|
||
return NDArray(r)
|
||
|
||
def array_split(ary, indices_or_sections, axis=0):
|
||
'''
|
||
Split an array into multiple sub-arrays.
|
||
|
||
:param ary: (*array*) Array to be divided into sub-arrays.
|
||
:param indices_or_sections: (*int or 1-D array*) If indices_or_sections is an integer, N, the array
|
||
will be divided into N equal arrays along axis. If indices_or_sections is a 1-D array of sorted
|
||
integers, the entries indicate where along axis the array is split.
|
||
:param axis: (*int*) Array to be divided into sub-arrays.
|
||
:return:
|
||
'''
|
||
if axis < 0:
|
||
axis = ary.ndim + axis
|
||
n = ary.shape[axis]
|
||
key = [slice(None)] * ary.ndim
|
||
si = 0
|
||
r = []
|
||
if isinstance(indices_or_sections, int):
|
||
sn = int(n / indices_or_sections)
|
||
sns = [sn] * indices_or_sections
|
||
m = n % indices_or_sections
|
||
if m > 0:
|
||
for i in range(m):
|
||
sns[i] = sn + 1
|
||
for sn in sns:
|
||
key[axis] = slice(si, si + sn, 1)
|
||
r.append(ary[tuple(key)])
|
||
si += sn
|
||
else:
|
||
for idx in indices_or_sections:
|
||
if idx > n:
|
||
idx = n
|
||
key[axis] = slice(si, idx, 1)
|
||
r.append(ary[tuple(key)])
|
||
si = idx
|
||
key[axis] = slice(si, n, 1)
|
||
r.append(ary[tuple(key)])
|
||
return r
|
||
|
||
def split(ary, indices_or_sections, axis=0):
|
||
'''
|
||
Split an array into multiple sub-arrays.
|
||
|
||
:param ary: (*array*) Array to be divided into sub-arrays.
|
||
:param indices_or_sections: (*int or 1-D array*) If indices_or_sections is an integer, N, the array
|
||
will be divided into N equal arrays along axis. If indices_or_sections is a 1-D array of sorted
|
||
integers, the entries indicate where along axis the array is split.
|
||
:param axis: (*int*) Array to be divided into sub-arrays.
|
||
:return:
|
||
'''
|
||
if axis < 0:
|
||
axis = ary.ndim + axis
|
||
n = ary.shape[axis]
|
||
if isinstance(indices_or_sections, int):
|
||
if n % indices_or_sections:
|
||
raise ValueError('array split does not result in an equal division')
|
||
return array_split(ary, indices_or_sections, axis)
|
||
|
||
def atleast_1d(*args):
|
||
'''
|
||
View inputs as arrays with at least one dimensions.
|
||
|
||
Parameters
|
||
----------
|
||
args1, args2, ... : array_like
|
||
One or more array-like sequences.
|
||
|
||
Returns
|
||
-------
|
||
res, res2, ... : array_like
|
||
An array, or list of arrays, each with ``a.ndim >= 1``.
|
||
'''
|
||
res = []
|
||
for arg in args:
|
||
arg = array(arg)
|
||
if arg.ndim == 0:
|
||
result = arg.reshape(1)
|
||
else:
|
||
result = arg
|
||
res.append(result)
|
||
if len(res) == 1:
|
||
return res[0]
|
||
else:
|
||
return res
|
||
|
||
|
||
def atleast_2d(*args):
|
||
'''
|
||
View inputs as arrays with at least two dimensions.
|
||
|
||
Parameters
|
||
----------
|
||
args1, args2, ... : array_like
|
||
One or more array-like sequences. Non-array inputs are converted
|
||
to arrays. Arrays that already have two or more dimensions are
|
||
preserved.
|
||
Returns
|
||
-------
|
||
res, res2, ... : array_like
|
||
An array, or list of arrays, each with ``a.ndim >= 2``.
|
||
Copies are avoided where possible, and views with two or more
|
||
dimensions are returned.
|
||
'''
|
||
res = []
|
||
for arg in args:
|
||
arg = array(arg)
|
||
if arg.ndim == 0:
|
||
result = arg.reshape(1, 1)
|
||
elif arg.ndim == 1:
|
||
result = arg.reshape(1,len(arg))
|
||
else:
|
||
result = arg
|
||
res.append(result)
|
||
if len(res) == 1:
|
||
return res[0]
|
||
else:
|
||
return res
|
||
|
||
def vstack(tup):
|
||
'''
|
||
Stack arrays in sequence vertically (row wise).
|
||
|
||
This is equivalent to concatenation along the first axis after 1-D arrays
|
||
of shape `(N,)` have been reshaped to `(1,N)`.
|
||
|
||
:param tup: (*tuple*) Sequence of array. The arrays must have the same shape
|
||
along all but the first axis. 1-D arrays must have the same length.
|
||
|
||
:returns: (*array*) The array formed by stacking the given arrays, will be
|
||
at least 2-D.
|
||
'''
|
||
return concatenate([atleast_2d(_m) for _m in tup], 0)
|
||
|
||
def hstack(tup):
|
||
'''
|
||
Stack arrays in sequence horizontally (column wise).
|
||
|
||
This is equivalent to concatenation along the second axis, except for 1-D
|
||
arrays where it concatenates along the first axis.
|
||
|
||
:param tup: (*tuple*) Sequence of array. The arrays must have the same shape
|
||
along all but the first axis. 1-D arrays must have the same length.
|
||
|
||
:returns: (*array*) The array formed by stacking the given arrays.
|
||
'''
|
||
arrs = [atleast_1d(_m) for _m in tup]
|
||
# As a special case, dimension 0 of 1-dimensional arrays is "horizontal"
|
||
if arrs and arrs[0].ndim == 1:
|
||
return concatenate(arrs, 0)
|
||
else:
|
||
return concatenate(arrs, 1)
|
||
|
||
|
||
def dot(a, b):
|
||
"""
|
||
Matrix multiplication.
|
||
|
||
:param a: (*2D Array*) Matrix a.
|
||
:param b: (*2D or 1D Array*) Matrix or vector b.
|
||
|
||
:returns: Result Matrix or vector.
|
||
"""
|
||
if isinstance(a, (int, long, float, complex)) and isinstance(b, (int, long, float, complex)):
|
||
return a * b
|
||
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
if isinstance(b, list):
|
||
b = array(b)
|
||
r = ArrayMath.dot(a.asarray(), b.asarray())
|
||
return NDArray(r)
|
||
|
||
def vdot(a, b):
|
||
'''
|
||
Return the dot product of two vectors.
|
||
|
||
Note that ``vdot`` handles multidimensional arrays differently than dot: it does not
|
||
perform a matrix product, but flattens input arguments to 1-D vectors first.
|
||
Consequently, it should only be used for vectors.
|
||
|
||
:param a: (*array_like*) First argument to the dot product.
|
||
:param b: (*array_like*) Second argument to the dot product.
|
||
|
||
:returns: (*float*) Dot product of ``a`` and ``b``.
|
||
'''
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
if isinstance(b, list):
|
||
b = array(b)
|
||
if a.ndim > 1:
|
||
a = a.flatten()
|
||
if b.ndim > 1:
|
||
b = b.flatten()
|
||
return ArrayMath.vdot(a.asarray(), b.asarray())
|
||
|
||
def shape(a):
|
||
'''
|
||
Return the shape of an array.
|
||
|
||
:param a: (*array_like*) Input array.
|
||
|
||
:return: (*tuple*) The elements of the shape tuple give the lengths of the corresponding array dimensions.
|
||
'''
|
||
try:
|
||
result = a.shape
|
||
except AttributeError:
|
||
result = asarray(a).shape
|
||
return result
|
||
|
||
def reshape(a, *args):
|
||
"""
|
||
Gives a new shape to an array without changing its data.
|
||
|
||
:param a: (*array_like*) Array to be reshaped.
|
||
:param shape: (*int or tuple of ints*) The new shape should be compatible with the original
|
||
shape. If an integer, then the result will be a 1-D array of that length. One shape
|
||
dimension can be -1. In this case, the value is inferred from the length of the array and
|
||
remaining dimensions.
|
||
|
||
:returns: Reshaped array.
|
||
"""
|
||
return a.reshape(*args)
|
||
|
||
def squeeze(a):
|
||
'''
|
||
Remove single-dimensional entries from the shape of an array.
|
||
|
||
:param a: (*array_like*) Input data array.
|
||
|
||
:returns: (*array_like*) The input array, but with all or a subset of the dimensions of length 1
|
||
removed.
|
||
'''
|
||
da = a.asarray()
|
||
da = da.reduce()
|
||
if type(a) is NDArray:
|
||
return NDArray(da)
|
||
else:
|
||
dims = []
|
||
for dim in a.dims:
|
||
if dim.getLength() > 1:
|
||
dims.append(dim)
|
||
return DimArray(NDArray(da), dims, a.fill_value, a.proj)
|
||
|
||
def ravel(a):
|
||
'''
|
||
Return a contiguous flattened array.
|
||
|
||
:param a: (*array*) Input array.
|
||
:return: A contiguous flattened array.
|
||
'''
|
||
return a.ravel()
|
||
|
||
def meshgrid(*args):
|
||
'''
|
||
Return coordinate matrices from coordinate vectors.
|
||
|
||
Make N-D coordinate arrays for vectorized evaluations of N-D scalar/vector fields
|
||
over N-D grids, given one-dimensional coordinate arrays x1, x2,…, xn.
|
||
|
||
:param x1,x2...xn: (*array_like*) 1-D arrays representing the coordinates of a grid..
|
||
|
||
:returns X1,X2...XN: For vectors x1, x2,…, ‘xn’ with lengths Ni=len(xi) ,
|
||
return (N1, N2, N3,...Nn) shaped arrays
|
||
'''
|
||
xs = []
|
||
for x in args:
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if x.ndim != 1:
|
||
print 'The paramters must be vector arrays!'
|
||
return None
|
||
xs.append(x._array)
|
||
|
||
ra = ArrayUtil.meshgrid(xs)
|
||
rs = []
|
||
for r in ra:
|
||
rs.append(NDArray(r))
|
||
return tuple(rs)
|
||
|
||
def meshgrid_bak(*args):
|
||
'''
|
||
Return coordinate matrices from coordinate vectors.
|
||
|
||
Make N-D coordinate arrays for vectorized evaluations of N-D scalar/vector fields
|
||
over N-D grids, given one-dimensional coordinate arrays x1, x2,…, xn.
|
||
|
||
:param x1,x2...xn: (*array_like*) 1-D arrays representing the coordinates of a grid..
|
||
|
||
:returns X1,X2...XN: For vectors x1, x2,…, ‘xn’ with lengths Ni=len(xi) ,
|
||
return (N1, N2, N3,...Nn) shaped arrays
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if isinstance(y, list):
|
||
y = array(y)
|
||
|
||
if x.ndim != 1 or y.ndim != 1:
|
||
print 'The paramters must be vector arrays!'
|
||
return None
|
||
|
||
xa = x.asarray()
|
||
ya = y.asarray()
|
||
ra = ArrayUtil.meshgrid(xa, ya)
|
||
return NDArray(ra[0]), NDArray(ra[1])
|
||
|
||
def broadcast_to(a, shape):
|
||
"""
|
||
Broadcast an array to a new shape.
|
||
|
||
:param a: (*array_like*) The array to broadcast.
|
||
:param shape: (*tuple*) The shape of the desired array.
|
||
|
||
:returns: (*NDArray*) A readonly view on the original array with the given shape.
|
||
"""
|
||
if isinstance(a, list):
|
||
a = array(a)
|
||
r = ArrayUtil.broadcast(a.asarray(), shape)
|
||
if r is None:
|
||
raise ValueError('Can not broadcast to the shape!')
|
||
return NDArray(r)
|
||
|
||
def corrcoef(x, y):
|
||
"""
|
||
Return Pearson product-moment correlation coefficients.
|
||
|
||
:param x: (*array_like*) A 1-D or 2-D array containing multiple variables and observations.
|
||
Each row of x represents a variable, and each column a single observation of all those
|
||
variables.
|
||
:param y: (*array_like*) An additional set of variables and observations. y has the same
|
||
shape as x.
|
||
|
||
:returns: The correlation coefficient matrix of the variables.
|
||
"""
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if isinstance(y, list):
|
||
y = array(y)
|
||
a = ArrayMath.getR(x.asarray(), y.asarray())
|
||
b = ArrayMath.getR(y.asarray(), x.asarray())
|
||
r = array([[1, a], [b, 1]])
|
||
return r
|
||
|
||
def linregress(x, y):
|
||
'''
|
||
Calculate a linear least-squares regression for two sets of measurements.
|
||
|
||
:param x, y: (*array_like*) Two sets of measurements. Both arrays should have the same length.
|
||
|
||
:returns: Result slope, intercept, relative coefficient, two-sided p-value for a hypothesis test
|
||
whose null hypothesis is that the slope is zero, standard error of the estimated gradient,
|
||
validate data number (remove NaN values).
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if isinstance(y, list):
|
||
y = array(y)
|
||
r = ArrayMath.lineRegress(x.asarray(), y.asarray())
|
||
return r[0], r[1], r[2], r[3], r[4], r[5]
|
||
|
||
def polyval(p, x):
|
||
"""
|
||
Evaluate a polynomial at specific values.
|
||
|
||
If p is of length N, this function returns the value:
|
||
|
||
p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]
|
||
|
||
If x is a sequence, then p(x) is returned for each element of x. If x is another polynomial then the
|
||
composite polynomial p(x(t)) is returned.
|
||
|
||
:param p: (*array_like*) 1D array of polynomial coefficients (including coefficients equal to zero)
|
||
from highest degree to the constant term.
|
||
:param x: (*array_like*) A number, an array of numbers, or an instance of poly1d, at which to evaluate
|
||
p.
|
||
|
||
:returns: Polynomial value
|
||
"""
|
||
return NDArray(ArrayMath.polyVal(p, x.asarray()))
|
||
|
||
def transpose(a, axes=None):
|
||
'''
|
||
Transpose 2-D array.
|
||
|
||
:param a: (*array*) 2-D array to be transposed.
|
||
:param axes: (*list of int*) By default, reverse the dimensions, otherwise permute the axes according to the
|
||
values given.
|
||
|
||
:returns: Transposed array.
|
||
'''
|
||
return a.transpose(axes)
|
||
|
||
def swapaxes(a, axis1, axis2):
|
||
'''
|
||
Interchange two axes of an array.
|
||
|
||
:param axis1: (*int*) First axis.
|
||
:param axis2: (*int*) Second axis.
|
||
|
||
:returns: Axes swapped array.
|
||
'''
|
||
return a.swapaxes(axis1, axis2)
|
||
|
||
def rot90(a, k=1):
|
||
"""
|
||
Rotate an array by 90 degrees in the counter-clockwise direction. The first two dimensions
|
||
are rotated if the array has more than 2 dimensions.
|
||
|
||
:param a: (*array_like*) Array for rotate.
|
||
:param k: (*int*) Number of times the array is rotated by 90 degrees
|
||
|
||
:returns: (*array_like*) Rotated array.
|
||
"""
|
||
r = ArrayMath.rot90(a.asarray(), k)
|
||
if type(a) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
dims = []
|
||
if Math.abs(k) == 1 or Math.abs(k) == 3:
|
||
dims.append(a.dims[1])
|
||
dims.append(a.dims[0])
|
||
for i in range(2, len(a.dims)):
|
||
dims.append(a.dims[i])
|
||
else:
|
||
for i in range(0, len(a.dims)):
|
||
dims.append(a.dims[i])
|
||
return DimArray(NDArray(r), dims, a.fill_value, a.proj)
|
||
|
||
def trapz(y, x=None, dx=1.0, axis=-1):
|
||
"""
|
||
Integrate along the given axis using the composite trapezoidal rule.
|
||
|
||
:param y: (*array_like*) Input array to integrate.
|
||
:param x: (*array_like*) Optional, If x is None, then spacing between all y elements is dx.
|
||
:param dx: (*scalar*) Optional, If x is None, spacing given by dx is assumed. Default is 1.
|
||
:param axis: (*int*) Optional, Specify the axis.
|
||
|
||
:returns: Definite integral as approximated by trapezoidal rule.
|
||
"""
|
||
if isinstance(y, list):
|
||
y = array(y)
|
||
|
||
if y.ndim == 1:
|
||
if x is None:
|
||
r = ArrayMath.trapz(y.asarray(), dx)
|
||
else:
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
r = ArrayMath.trapz(y.asarray(), x.asarray())
|
||
return r
|
||
else:
|
||
if axis == -1:
|
||
shape = y.shape
|
||
for i in range(y.ndim):
|
||
if shape[i] > 1:
|
||
axis = i
|
||
break
|
||
if x is None:
|
||
r = ArrayMath.trapz(y.asarray(), dx, axis)
|
||
else:
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
r = ArrayMath.trapz(y.asarray(), x.asarray(), axis)
|
||
if type(y) is NDArray:
|
||
return NDArray(r)
|
||
else:
|
||
dims = []
|
||
for i in range(0, y.ndim):
|
||
if i != axis:
|
||
dims.append(y.dims[i])
|
||
return DimArray(NDArray(r), dims, y.fill_value, y.proj)
|
||
|
||
def rolling_mean(x, window, center=False):
|
||
'''
|
||
Moving average function
|
||
|
||
:param x: (*array_like*) Input data array. Must be vector (one dimension).
|
||
:param window: (*int*) Size of the moving window.
|
||
:param center: (*boolean*) Set the labels at the center of the window. Default is ``False``.
|
||
|
||
:returns: (*array_like*) Moving averaged array.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
r = ArrayMath.rolling_mean(x.asarray(), window, center)
|
||
return NDArray(r)
|
||
|
||
def smooth5(x):
|
||
'''
|
||
Performs a 5 point smoothing to the 2D array x.
|
||
|
||
The result at each grid point is a weighted average of the grid point plus the 4
|
||
surrounding points. The center point receives a wieght of 1.0, the points at each side
|
||
and above and below receive a weight of 0.5.
|
||
|
||
All 5 points are multiplied by their weights and summed, then divided by the total
|
||
weight to obtain the smoothed value. Any missing data points are not included in the
|
||
sum; points beyond the grid boundary are considered to be missing. Thus the final result
|
||
may be the result of an averaging with less than 5 points.
|
||
|
||
:param x: (*array_like*) Input 2D array.
|
||
|
||
:returned: (*array*) Smoothed 2D array.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if x.ndim != 2:
|
||
print 'The array must be 2 dimension!'
|
||
raise ValueError()
|
||
r = ArrayUtil.smooth5(x._array)
|
||
if isinstance(x, DimArray):
|
||
return DimArray(r, x.dims, x.fill_value, x.proj)
|
||
else:
|
||
return NDArray(r)
|
||
|
||
def smooth9(x):
|
||
'''
|
||
Performs a 9 point smoothing to the 2D array x.
|
||
|
||
The result at each grid point is a weighted average of the grid point plus the 4
|
||
surrounding points. The center point receives a wieght of 1.0, the points at each side
|
||
and above and below receive a weight of 0.5, and corner points receive a weight of 0.3.
|
||
|
||
All 9 points are multiplied by their weights and summed, then divided by the total
|
||
weight to obtain the smoothed value. Any missing data points are not included in the
|
||
sum; points beyond the grid boundary are considered to be missing. Thus the final result
|
||
may be the result of an averaging with less than 9 points.
|
||
|
||
:param x: (*array_like*) Input 2D array.
|
||
|
||
:returned: (*array*) Smoothed 2D array.
|
||
'''
|
||
if isinstance(x, list):
|
||
x = array(x)
|
||
if x.ndim != 2:
|
||
print 'The array must be 2 dimension!'
|
||
raise ValueError()
|
||
r = ArrayUtil.smooth9(x._array)
|
||
if isinstance(x, DimArray):
|
||
return DimArray(r, x.dims, x.fill_value, x.proj)
|
||
else:
|
||
return NDArray(r)
|
||
|
||
def cdiff(a, dimidx):
|
||
'''
|
||
Performs a centered difference operation on a array in a specific direction
|
||
|
||
:param a: (*array*) The input array.
|
||
:param dimidx: (*int*) Demension index of the specific direction.
|
||
|
||
:returns: Result array.
|
||
'''
|
||
if isinstance(a, DimArray):
|
||
r = ArrayMath.cdiff(a.asarray(), dimidx)
|
||
return DimArray(NDArray(r), a.dims, a.fill_value, a.proj)
|
||
else:
|
||
return NDArray(ArrayMath.cdiff(a.asarray(), dimidx))
|
||
|
||
# Calculates the vertical component of the curl (ie, vorticity)
|
||
def hcurl(u, v):
|
||
'''
|
||
Calculates the vertical component of the curl (ie, vorticity). The data should be lon/lat projection.
|
||
|
||
:param u: (*array*) U component array.
|
||
:param v: (*array*) V component array.
|
||
|
||
:returns: Array of the vertical component of the curl.
|
||
'''
|
||
if isinstance(u, DimArray) and isinstance(v, DimArray):
|
||
ydim = u.ydim()
|
||
xdim = u.xdim()
|
||
r = ArrayMath.hcurl(u.asarray(), v.asarray(), xdim.getDimValue(), ydim.getDimValue())
|
||
return DimArray(NDArray(r), u.dims, u.fill_value, u.proj)
|
||
|
||
# Calculates the horizontal divergence using finite differencing
|
||
def hdivg(u, v):
|
||
'''
|
||
Calculates the horizontal divergence using finite differencing. The data should be lon/lat projection.
|
||
|
||
:param u: (*array*) U component array.
|
||
:param v: (*array*) V component array.
|
||
|
||
:returns: Array of the horizontal divergence.
|
||
'''
|
||
if isinstance(u, DimArray) and isinstance(v, DimArray):
|
||
ydim = u.ydim()
|
||
xdim = u.xdim()
|
||
r = ArrayMath.hdivg(u.asarray(), v.asarray(), xdim.getDimValue(), ydim.getDimValue())
|
||
return DimArray(NDArray(r), u.dims, u.fill_value, u.proj)
|
||
|
||
def magnitude(u, v):
|
||
'''
|
||
Performs the calculation: sqrt(u*u+v*v).
|
||
|
||
:param u: (*array*) U component array.
|
||
:param v: (*array*) V component array.
|
||
|
||
:returns: Result array.
|
||
'''
|
||
if isinstance(u, DimArray) and isinstance(v, DimArray):
|
||
r = ArrayMath.magnitude(u.asarray(), v.asarray())
|
||
return DimArray(NDArray(r), u.dims, u.fill_value, u.proj)
|
||
elif isinstance(u, NDArray) and isinstance(v, NDArray):
|
||
r = ArrayMath.magnitude(u.asarray(), v.asarray())
|
||
return NDArray(r)
|
||
else:
|
||
r = sqrt(u * u + v * v)
|
||
return r
|
||
|
||
def asarray(data, dtype=None):
|
||
'''
|
||
Convert the array_like data to NDArray data.
|
||
|
||
:param data: (*array_like*) The input data.
|
||
:param dtype: (*datatype*) Data type.
|
||
|
||
:returns: NDArray data.
|
||
'''
|
||
if isinstance(data, Array):
|
||
data = NDArray(data)
|
||
if isinstance(data, NDArray):
|
||
if dtype is None:
|
||
return data
|
||
else:
|
||
return a.astype(dtype)
|
||
else:
|
||
return array(data, dtype)
|
||
|
||
def asanyarray(data, dtype=None):
|
||
'''
|
||
Convert the array_like data to NDArray data.
|
||
|
||
:param data: (*array_like*) The input data.
|
||
:param dtype: (*datatype*) Data type.
|
||
|
||
:returns: NDArray data.
|
||
'''
|
||
return asarray(data, dtype)
|
||
|
||
def asmiarray(data):
|
||
'''
|
||
Convert the array_like data to NDArray data.
|
||
|
||
:param data: (*array_like*) The input data.
|
||
|
||
:returns: NDArray data.
|
||
'''
|
||
if isinstance(data, Array):
|
||
return NDArray(data)
|
||
elif isinstance(data, NDArray):
|
||
return data
|
||
else:
|
||
return array(data)
|
||
|
||
def asgriddata(data, x=None, y=None, fill_value=-9999.0):
|
||
if x is None:
|
||
if isinstance(data, PyGridData):
|
||
return data
|
||
elif isinstance(data, DimArray):
|
||
return data.asgriddata()
|
||
elif isinstance(data, NDArray):
|
||
if x is None:
|
||
x = arange(0, data.shape[1])
|
||
if y is None:
|
||
y = arange(0, data.shape[0])
|
||
gdata = GridData(data._array, x._array, y._array, fill_value)
|
||
return PyGridData(gdata)
|
||
else:
|
||
return None
|
||
else:
|
||
gdata = GridData(data.asarray(), x.asarray(), y.asarray(), fill_value)
|
||
return PyGridData(gdata)
|
||
|
||
def asgridarray(data, x=None, y=None, fill_value=-9999.0):
|
||
if x is None:
|
||
if isinstance(data, PyGridData):
|
||
return data.data.toGridArray()
|
||
elif isinstance(data, DimArray):
|
||
return data.asgridarray()
|
||
elif isinstance(data, NDArray):
|
||
if x is None:
|
||
x = arange(0, data.shape[1])
|
||
if y is None:
|
||
y = arange(0, data.shape[0])
|
||
gdata = GridArray(data._array, x._array, y._array, fill_value)
|
||
return gdata
|
||
else:
|
||
return None
|
||
else:
|
||
gdata = GridArray(data.asarray(), x.asarray(), y.asarray(), fill_value)
|
||
return gdata
|
||
|
||
def asstationdata(data, x, y, fill_value=-9999.0):
|
||
stdata = StationData(data.asarray(), x.asarray(), y.asarray(), fill_value)
|
||
return PyStationData(stdata)
|
||
|
||
def linint2(*args, **kwargs):
|
||
"""
|
||
Interpolates from a rectilinear grid to another rectilinear grid using bilinear interpolation.
|
||
|
||
:param x: (*array_like*) X coordinate array of the sample data (one dimension).
|
||
:param y: (*array_like*) Y coordinate array of the sample data (one dimension).
|
||
:param z: (*array_like*) Value array of the sample data (muti-dimension, last two dimensions are y and x).
|
||
:param xq: (*array_like*) X coordinate array of the query data (one dimension).
|
||
:param yq: (*array_like*) Y coordinate array of the query data (one dimension).
|
||
|
||
:returns: (*array_like*) Interpolated array.
|
||
"""
|
||
if len(args) == 3:
|
||
z = args[0]
|
||
x = z.dimvalue(z.ndim - 1)
|
||
y = z.dimvalue(z.ndim - 2)
|
||
xq = args[1]
|
||
yq = args[2]
|
||
else:
|
||
x = args[0]
|
||
y = args[1]
|
||
z = args[2]
|
||
xq = args[3]
|
||
yq = args[4]
|
||
x = array(x)._array
|
||
y = array(y)._array
|
||
z = array(z)._array
|
||
xq = array(xq)._array
|
||
yq = array(yq)._array
|
||
r = ArrayUtil.linint2(z, x, y, xq, yq)
|
||
return NDArray(r)
|
||
|
||
def interp2d(*args, **kwargs):
|
||
"""
|
||
Interpolate over a 2-D grid.
|
||
|
||
:param x: (*array_like*) X coordinate array of the sample points.
|
||
:param y: (*array_like*) Y coordinate array of the sample points.
|
||
:param z: (*array_like*) 2-D value array of the sample points.
|
||
:param xq: (*array_like*) X coordinate array of the query points.
|
||
:param yq: (*array_like*) Y coordinate array of the query points.
|
||
:param kind: (*string*) The kind of the interpolation method. ['linear' | 'nearest'].
|
||
|
||
:returns: (*array_like*) Interpolated array.
|
||
"""
|
||
if len(args) == 3:
|
||
z = args[0]
|
||
x = z.dimvalue(1)
|
||
y = z.dimvalue(0)
|
||
xq = args[1]
|
||
yq = args[2]
|
||
else:
|
||
x = args[0]
|
||
y = args[1]
|
||
z = args[2]
|
||
xq = args[3]
|
||
yq = args[4]
|
||
x = array(x)._array
|
||
y = array(y)._array
|
||
z = array(z)._array
|
||
xq = array(xq)._array
|
||
yq = array(yq)._array
|
||
kind = kwargs.pop('kind', 'linear')
|
||
if kind == 'neareast':
|
||
r = ArrayUtil.resample_Neighbor(z, x, y, xq, yq)
|
||
else:
|
||
r = ArrayUtil.resample_Bilinear(z, x, y, xq, yq)
|
||
if r.getSize() == 1:
|
||
return r.getDouble(0)
|
||
else:
|
||
return NDArray(r)
|
||
|
||
def interpn(points, values, xi):
|
||
"""
|
||
Multidimensional interpolation on regular grids.
|
||
|
||
:param points: (*list*) The points defining the regular grid in n dimensions.
|
||
:param values: (*array_like*) The data on the regular grid in n dimensions.
|
||
:param xi: (*array_like*) The coordinates to sample the gridded data at.
|
||
|
||
:returns: (*float*) Interpolated value at input coordinates.
|
||
"""
|
||
npoints = []
|
||
for p in points:
|
||
if isinstance(p, (list,tuple)):
|
||
p = array(p)
|
||
npoints.append(p._array)
|
||
|
||
if isinstance(xi, (list, tuple)):
|
||
if isinstance(xi[0], NDArray):
|
||
nxi = []
|
||
for x in xi:
|
||
nxi.append(x._array)
|
||
else:
|
||
nxi = []
|
||
for x in xi:
|
||
if isinstance(x, datetime.datetime):
|
||
x = miutil.date2num(x)
|
||
nxi.append(x)
|
||
nxi = array(nxi)._array
|
||
else:
|
||
nxi = nxi._array
|
||
r = ArrayUtil.interpn(npoints, values._array, nxi)
|
||
if isinstance(r, Array):
|
||
return NDArray(r)
|
||
else:
|
||
return r
|
||
|
||
def griddata(points, values, xi=None, **kwargs):
|
||
'''
|
||
Interpolate scattered data to grid data.
|
||
|
||
:param points: (*list*) The list contains x and y coordinate arrays of the scattered data.
|
||
:param values: (*array_like*) The scattered data array.
|
||
:param xi: (*list*) The list contains x and y coordinate arrays of the grid data. Default is ``None``,
|
||
the grid x and y coordinate size were both 500.
|
||
:param method: (*string*) The interpolation method. [idw | cressman | nearest | inside | inside_min
|
||
| inside_max | inside_count | surface | barnes]
|
||
:param fill_value: (*float*) Fill value, Default is ``nan``.
|
||
:param pointnum: (*int*) Only used for 'idw' method. The number of the points to be used for each grid
|
||
value interpolation.
|
||
:param radius: (*float*) Used for 'idw', 'cressman' and 'neareast' methods. The searching raduis. Default
|
||
is ``None`` in 'idw' method, means no raduis was used. Default is ``[10, 7, 4, 2, 1]`` in cressman
|
||
method.
|
||
:param centerpoint: (*boolean*) The grid points located at center or border of grid. Default
|
||
is True (pont at center of grid).
|
||
:param convexhull: (*boolean*) If the convexhull will be used to mask result grid data. Default is ``False``.
|
||
|
||
:returns: (*array*) Interpolated grid data (2-D array)
|
||
'''
|
||
method = kwargs.pop('method', 'idw')
|
||
x_s = points[0]
|
||
y_s = points[1]
|
||
if xi is None:
|
||
xn = 500
|
||
yn = 500
|
||
x_g = linspace(x_s.min(), x_s.max(), xn)
|
||
y_g = linspace(y_s.min(), y_s.max(), yn)
|
||
else:
|
||
x_g = xi[0]
|
||
y_g = xi[1]
|
||
if isinstance(values, NDArray):
|
||
values = values.asarray()
|
||
if method == 'idw':
|
||
radius = kwargs.pop('radius', None)
|
||
if radius is None:
|
||
pnum = kwargs.pop('pointnum', None)
|
||
r = InterpUtil.interpolation_IDW_Neighbor(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), pnum)
|
||
else:
|
||
pnum = kwargs.pop('pointnum', 2)
|
||
r = InterpUtil.interpolation_IDW_Radius(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), pnum, radius)
|
||
elif method == 'cressman':
|
||
radius = kwargs.pop('radius', [10, 7, 4, 2, 1])
|
||
if isinstance(radius, NDArray):
|
||
radius = radius.aslist()
|
||
r = InterpUtil.cressman(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), radius)
|
||
elif method == 'barnes':
|
||
kappa = kwargs.pop('kappa', 1)
|
||
gamma = kwargs.pop('gamma', 1)
|
||
radius = kwargs.pop('radius', [10, 7, 4, 2, 1])
|
||
if radius is None:
|
||
r = InterpUtil.barnes(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), kappa, gamma)
|
||
else:
|
||
if isinstance(radius, NDArray):
|
||
radius = radius.aslist()
|
||
r = InterpUtil.barnes(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), radius, kappa, gamma)
|
||
elif method == 'nearest':
|
||
radius = kwargs.pop('radius', inf)
|
||
r = InterpUtil.interpolation_Nearest(x_s.asarray(), y_s.asarray(), values, x_g.asarray(), y_g.asarray(), radius)
|
||
elif method == 'inside' or method == 'inside_mean':
|
||
centerpoint = kwargs.pop('centerpoint', True)
|
||
r = InterpUtil.interpolation_Inside_Mean(x_s.asarray(), y_s.asarray(), values, x_g.asarray(), y_g.asarray(), centerpoint)
|
||
elif method == 'inside_max':
|
||
centerpoint = kwargs.pop('centerpoint', True)
|
||
r = InterpUtil.interpolation_Inside_Max(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), centerpoint)
|
||
elif method == 'inside_min':
|
||
centerpoint = kwargs.pop('centerpoint', True)
|
||
r = InterpUtil.interpolation_Inside_Min(x_s.aslist(), y_s.aslist(), values, x_g.aslist(), y_g.aslist(), centerpoint)
|
||
elif method == 'inside_count':
|
||
centerpoint = kwargs.pop('centerpoint', True)
|
||
r = InterpUtil.interpolation_Inside_Count(x_s.aslist(), y_s.aslist(), x_g.aslist(), y_g.aslist(), True, centerpoint)
|
||
return NDArray(r[0]), x_g, y_g, NDArray(r[1])
|
||
elif method == 'surface':
|
||
r = InterpUtil.interpolation_Surface(x_s.asarray(), y_s.asarray(), values, x_g.asarray(), y_g.asarray())
|
||
else:
|
||
return None
|
||
|
||
convexhull = kwargs.pop('convexhull', False)
|
||
if convexhull:
|
||
polyshape = GeometryUtil.convexHull(x_s.asarray(), y_s.asarray())
|
||
x_gg, y_gg = meshgrid(x_g, y_g)
|
||
r = GeometryUtil.maskout(r, x_gg._array, y_gg._array, [polyshape])
|
||
return NDArray(r), x_g, y_g
|
||
else:
|
||
return NDArray(r), x_g, y_g
|
||
|
||
def pol2cart(theta, rho):
|
||
'''
|
||
Transform polar coordinates to Cartesian
|
||
|
||
:param theta: (*array_like*) Theta value in polar coordinates
|
||
:param rho: (*array_like*) Rho value in polar coordinates
|
||
|
||
:returns: x and y value in Cartesian coordinates
|
||
'''
|
||
if isinstance(theta, (int, float)):
|
||
r = ArrayMath.polarToCartesian(theta, rho)
|
||
return r[0], r[1]
|
||
else:
|
||
theta = array(theta)
|
||
rho = array(rho)
|
||
r = ArrayMath.polarToCartesian(theta._array, rho._array)
|
||
return NDArray(r[0]), NDArray(r[1])
|
||
|
||
def cart2pol(x, y):
|
||
'''
|
||
Transform Cartesian coordinates to polar
|
||
|
||
:param x: (*array_like*) X value in Cartesian coordinates
|
||
:param y: (*array_like*) Y value in Cartesian coordinates
|
||
|
||
:returns: Theta and rho value in polar coordinates
|
||
'''
|
||
if isinstance(x, (int, float)):
|
||
r = ArrayMath.cartesianToPolar(x, y)
|
||
return r[0], r[1]
|
||
else:
|
||
x = array(x)
|
||
y = array(y)
|
||
r = ArrayMath.cartesianToPolar(x._array, y._array)
|
||
return NDArray(r[0]), NDArray(r[1])
|
||
|
||
def addtimedim(infn, outfn, t, tunit='hours'):
|
||
'''
|
||
Add a time dimension to a netCDF data file.
|
||
|
||
:param infn: (*string*) Input netCDF file name.
|
||
:param outfn: (*string*) Output netCDF file name.
|
||
:param t: (*DateTime*) A time value.
|
||
:param tunit: (*string*) Time unite, Default is ``hours``.
|
||
|
||
:returns: The new netCDF with time dimension.
|
||
'''
|
||
cal = Calendar.getInstance()
|
||
cal.set(t.year, t.month - 1, t.day, t.hour, t.minute, t.second)
|
||
nt = cal.getTime()
|
||
NetCDFDataInfo.addTimeDimension(infn, outfn, nt, tunit)
|
||
|
||
def joinncfile(infns, outfn, tdimname):
|
||
'''
|
||
Join several netCDF files to one netCDF file.
|
||
|
||
:param infns: (*list*) Input netCDF file name list.
|
||
:param outfn: (*string*) Output netCDF file name.
|
||
:param tdimname: (*string*) Time dimension name.
|
||
|
||
:returns: Joined netCDF file.
|
||
'''
|
||
NetCDFDataInfo.joinDataFiles(infns, outfn, tdimname)
|
||
|
||
# Get month abstract English name
|
||
def monthname(m):
|
||
'''
|
||
Get month abstract English name.
|
||
|
||
:param m: (*int*) Month number (1 to 12).
|
||
'''
|
||
mmm = 'jan'
|
||
if m == 1:
|
||
mmm = 'jan'
|
||
elif m == 2:
|
||
mmm = 'feb'
|
||
elif m == 3:
|
||
mmm = 'mar'
|
||
elif m == 4:
|
||
mmm = 'apr'
|
||
elif m == 5:
|
||
mmm = 'may'
|
||
elif m == 6:
|
||
mmm = 'jun'
|
||
elif m == 7:
|
||
mmm = 'jul'
|
||
elif m == 8:
|
||
mmm = 'aug'
|
||
elif m == 9:
|
||
mmm = 'sep'
|
||
elif m == 10:
|
||
mmm = 'oct'
|
||
elif m == 11:
|
||
mmm = 'nov'
|
||
elif m == 12:
|
||
mmm = 'dec'
|
||
|
||
return mmm |