mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
add append, insert, delete functions in numeric package
This commit is contained in:
parent
ed90ae3529
commit
ab15b26724
@ -331,7 +331,11 @@ public class MeshGraphic extends GraphicCollection3D {
|
||||
vertexColor = new float[getVertexNumber() * 4];
|
||||
float[] color;
|
||||
for (int i = 0; i < vertexValue.length; i++) {
|
||||
color = legendScheme.findLegendBreak(vertexValue[i]).getColor().getRGBComponents(null);
|
||||
if (Float.isNaN(vertexValue[i])) {
|
||||
color = legendScheme.getLegendBreak(0).getColor().getRGBComponents(null);
|
||||
} else {
|
||||
color = legendScheme.findLegendBreak(vertexValue[i]).getColor().getRGBComponents(null);
|
||||
}
|
||||
System.arraycopy(color, 0, vertexColor, i * 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ import java.util.zip.ZipInputStream;
|
||||
public static String getVersion(){
|
||||
String version = GlobalUtil.class.getPackage().getImplementationVersion();
|
||||
if (version == null || version.equals("")) {
|
||||
version = "3.6.5";
|
||||
version = "3.6.6";
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
@ -601,7 +601,7 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
|
||||
Section section = new Section(origin, size, stride);
|
||||
RadialRecord record = this.recordMap.get(varName);
|
||||
Array dataArray = Array.factory(record.getDataType(), section.getShape());
|
||||
Array dataArray = Array.factory(DataType.FLOAT, section.getShape());
|
||||
Range zRange = section.getRange(0);
|
||||
Range yRange = section.getRange(1);
|
||||
Range xRange = section.getRange(2);
|
||||
@ -623,36 +623,36 @@ public class CMARadarBaseDataInfo extends DataInfo implements IGridDataInfo {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Attribute aoAttr = variable.findAttribute("add_offset");
|
||||
Attribute sfAttr = variable.findAttribute("scale_factor");
|
||||
if (aoAttr != null || sfAttr != null) {
|
||||
Number add_offset = 0.f;
|
||||
Number scale_factor = 1.f;
|
||||
if (aoAttr != null) {
|
||||
switch (aoAttr.getDataType()) {
|
||||
case DOUBLE:
|
||||
add_offset = aoAttr.getValues().getDouble(0);
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
add_offset = aoAttr.getValues().getFloat(0);
|
||||
break;
|
||||
}
|
||||
Attribute aoAttr = variable.findAttribute("add_offset");
|
||||
Attribute sfAttr = variable.findAttribute("scale_factor");
|
||||
if (aoAttr != null || sfAttr != null) {
|
||||
Number add_offset = 0.f;
|
||||
Number scale_factor = 1.f;
|
||||
if (aoAttr != null) {
|
||||
switch (aoAttr.getDataType()) {
|
||||
case DOUBLE:
|
||||
add_offset = aoAttr.getValues().getDouble(0);
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
add_offset = aoAttr.getValues().getFloat(0);
|
||||
break;
|
||||
}
|
||||
if (sfAttr != null) {
|
||||
switch (sfAttr.getDataType()) {
|
||||
case DOUBLE:
|
||||
scale_factor = sfAttr.getValues().getDouble(0);
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
scale_factor = sfAttr.getValues().getFloat(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataArray = ArrayMath.div(ArrayMath.sub(dataArray, add_offset), scale_factor);
|
||||
}
|
||||
if (sfAttr != null) {
|
||||
switch (sfAttr.getDataType()) {
|
||||
case DOUBLE:
|
||||
scale_factor = sfAttr.getValues().getDouble(0);
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
scale_factor = sfAttr.getValues().getFloat(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataArray = ArrayMath.div(ArrayMath.sub(dataArray, add_offset), scale_factor);
|
||||
}
|
||||
|
||||
return dataArray;
|
||||
|
||||
@ -8,27 +8,27 @@
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\no_opengl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\radar"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array\complex"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\radar"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_geo.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\array\gradient_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_3d.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\array\delete_1.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_geo.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\array\gradient_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\radar\radar_bz2_3d.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\array\delete_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -36,5 +36,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1311,742"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
|
||||
</MeteoInfo>
|
||||
|
||||
@ -26,9 +26,9 @@ class RadarDataFile(DimDataFile):
|
||||
:return: Scan elevation angles.
|
||||
"""
|
||||
if product is None:
|
||||
return list(self.datainfo.getElevations())
|
||||
return np.array(self.datainfo.getElevations())
|
||||
else:
|
||||
return list(self.datainfo.getElevations(product))
|
||||
return np.array(self.datainfo.getElevations(product))
|
||||
|
||||
def get_vcs_data(self, product, start_point, end_point):
|
||||
"""
|
||||
|
||||
@ -19,19 +19,43 @@ def antenna_to_cartesian(distance, azimuth, elevation, h=None):
|
||||
"""
|
||||
azimuth = np.deg2rad(azimuth)
|
||||
elevation = np.deg2rad(elevation)
|
||||
nd = distance.shape[0]
|
||||
na = azimuth.shape[0]
|
||||
distance, azimuth = np.meshgrid(distance, azimuth)
|
||||
if isinstance(elevation, np.NDArray):
|
||||
elevation = elevation.reshape(na, 1)
|
||||
elevation = elevation.repeat(nd, axis=1)
|
||||
elevation = elevation._array
|
||||
if h is None:
|
||||
r = Transform.antennaToCartesian(distance._array, azimuth._array, elevation)
|
||||
else:
|
||||
r = Transform.antennaToCartesian(distance._array, azimuth._array, elevation, h)
|
||||
if azimuth.ndim == 1:
|
||||
nd = distance.shape[0]
|
||||
na = azimuth.shape[0]
|
||||
distance, azimuth = np.meshgrid(distance, azimuth)
|
||||
if isinstance(elevation, np.NDArray):
|
||||
elevation = elevation.reshape(na, 1)
|
||||
elevation = elevation.repeat(nd, axis=1)
|
||||
elevation = elevation._array
|
||||
if h is None:
|
||||
r = Transform.antennaToCartesian(distance._array, azimuth._array, elevation)
|
||||
else:
|
||||
r = Transform.antennaToCartesian(distance._array, azimuth._array, elevation, h)
|
||||
|
||||
return np.array(r[0]), np.array(r[1]), np.array(r[2])
|
||||
return np.array(r[0]), np.array(r[1]), np.array(r[2])
|
||||
else:
|
||||
nd = distance.shape[0]
|
||||
ns, na = azimuth.shape
|
||||
x = np.empty((ns, na, nd))
|
||||
y = np.empty((ns, na, nd))
|
||||
z = np.empty((ns,na,nd))
|
||||
for i in range(ns):
|
||||
dis, azi = np.meshgrid(distance, azimuth[i])
|
||||
if elevation.ndim == 1:
|
||||
ele = elevation[i]
|
||||
else:
|
||||
ele = elevation[i].reshape(na, 1).copy()
|
||||
ele = ele.repeat(nd, axis=1)
|
||||
ele = ele._array
|
||||
if h is None:
|
||||
r = Transform.antennaToCartesian(dis._array, azi._array, ele)
|
||||
else:
|
||||
r = Transform.antennaToCartesian(dis._array, azi._array, ele, h)
|
||||
x[i] = np.array(r[0])
|
||||
y[i] = np.array(r[1])
|
||||
z[i] = np.array(r[2])
|
||||
|
||||
return x, y, z
|
||||
|
||||
def antenna_to_geographic(lon, lat, distance, azimuth, elevation, h=None):
|
||||
"""
|
||||
|
||||
@ -80,7 +80,10 @@ class NDArray(object):
|
||||
return self.dtype.itemsize
|
||||
|
||||
def __len__(self):
|
||||
return self._shape[0]
|
||||
if self.ndim == 0:
|
||||
return 0
|
||||
else:
|
||||
return self._shape[0]
|
||||
|
||||
def __str__(self):
|
||||
return ArrayUtil.convertToString(self._array)
|
||||
@ -296,10 +299,10 @@ class NDArray(object):
|
||||
step = 1
|
||||
alllist = False
|
||||
elif isinstance(k, (list, tuple, NDArray)):
|
||||
if isinstance(k, NDArray):
|
||||
k = k.aslist()
|
||||
if isinstance(k, (list, tuple)):
|
||||
k = NDArray(k)
|
||||
onlyrange = False
|
||||
ranges.append(k)
|
||||
ranges.append(k._array)
|
||||
continue
|
||||
else:
|
||||
sidx = 0 if k.start is None else k.start
|
||||
@ -517,6 +520,32 @@ class NDArray(object):
|
||||
else:
|
||||
raise StopIteration()
|
||||
|
||||
def item(self, *args):
|
||||
"""
|
||||
Copy an element of an array to a standard Python scalar and return it.
|
||||
|
||||
:param args: none: in this case, the method only works for arrays with one element
|
||||
(a.size == 1), which element is copied into a standard Python scalar object and returned.
|
||||
int_type: this argument is interpreted as a flat index into the array, specifying which
|
||||
element to copy and return.
|
||||
tuple of int_types: functions as does a single int_type argument, except that the argument
|
||||
is interpreted as a nd-index into the array.
|
||||
|
||||
:return: A copy of the specified element of the array as a suitable Python scalar
|
||||
"""
|
||||
if self.ndim == 0:
|
||||
return self._array.get()
|
||||
else:
|
||||
index = self._array.getIndex()
|
||||
if len(args) == 1:
|
||||
if isinstance(args[0], int):
|
||||
index.setCurrentIndex(args[0])
|
||||
else:
|
||||
index.set(args[0])
|
||||
elif len(args) > 1:
|
||||
index.set(args)
|
||||
return self._array.getObject(index)
|
||||
|
||||
def copy(self):
|
||||
"""
|
||||
Copy array values to a new array.
|
||||
|
||||
Binary file not shown.
@ -40,7 +40,7 @@ __all__ = [
|
||||
'argmin','argmax','argsort','array','array_split','amax','amin','asanyarray','asarray','asgridarray',
|
||||
'asgriddata','arcsin','asin','asmiarray','asstationdata','atleast_1d','atleast_2d','arctan','atan',
|
||||
'arctan2','atan2','ave_month','average','histogram','broadcast_to','cdiff','ceil',
|
||||
'concatenate','conj','conjugate','corrcoef','cos','cosh','cylinder','degrees','delete','delnan','diag','diff',
|
||||
'concatenate','conj','conjugate','corrcoef','cos','cosh','cylinder','degrees','delnan','diag','diff',
|
||||
'datatable','dot','empty','empty_like','exp','eye','flatnonzero','floor',
|
||||
'fmax','fmin','full','hcurl','hdivg','hstack','hypot','identity','indices','interp2d','interpn','isarray',
|
||||
'isclose','isfinite','isinf','isnan','isscalar','linspace','log','log10','logical_not','logspace',
|
||||
@ -65,7 +65,7 @@ def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
|
||||
:param dtype: (*DataType*) Data type
|
||||
:param copy: (*bool*) If true (default), then the object is copied.
|
||||
:param order: (*str*) Specify the memory layout of the array.
|
||||
:param subok: (*bool*) If True, then sub-classes will be passed-through,
|
||||
:param subok: (*bool*) If True, then subclasses will be passed-through,
|
||||
otherwise the returned array will be forced to be a base-class array (default).
|
||||
:param ndmin: (*int*) Specifies the minimum number of dimensions that the
|
||||
resulting array should have.
|
||||
@ -1753,8 +1753,8 @@ def argsort(a, axis=-1):
|
||||
: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.
|
||||
: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)
|
||||
@ -1992,7 +1992,7 @@ def concatenate(arrays, axis=0):
|
||||
"""
|
||||
ars = []
|
||||
for a in arrays:
|
||||
ars.append(a.asarray())
|
||||
ars.append(asanyarray(a).asarray())
|
||||
r = ArrayUtil.concatenate(ars, axis)
|
||||
return NDArray(r)
|
||||
|
||||
@ -2801,7 +2801,7 @@ def smooth5(x):
|
||||
if isinstance(x, list):
|
||||
x = array(x)
|
||||
if x.ndim != 2:
|
||||
print 'The array must be 2 dimension!'
|
||||
print('The array must be 2 dimension!')
|
||||
raise ValueError()
|
||||
r = ArrayUtil.smooth5(x._array)
|
||||
if isinstance(x, DimArray):
|
||||
@ -2829,7 +2829,7 @@ def smooth9(x):
|
||||
if isinstance(x, list):
|
||||
x = array(x)
|
||||
if x.ndim != 2:
|
||||
print 'The array must be 2 dimension!'
|
||||
print('The array must be 2 dimension!')
|
||||
raise ValueError()
|
||||
r = ArrayUtil.smooth9(x._array)
|
||||
if isinstance(x, DimArray):
|
||||
|
||||
@ -4,8 +4,10 @@ from ..core import dtype
|
||||
from ..core._ndarray import NDArray
|
||||
from ..core.fromnumeric import (ravel, nonzero)
|
||||
from org.meteoinfo.ndarray.math import ArrayMath
|
||||
import warnings
|
||||
|
||||
__all__ = ['angle','extract', 'place', 'grid_edge', 'gradient']
|
||||
__all__ = ['angle','extract', 'place', 'grid_edge', 'gradient', 'append',
|
||||
'delete', 'insert']
|
||||
|
||||
|
||||
def extract(condition, arr):
|
||||
@ -366,3 +368,401 @@ def gradient(f, *varargs, **kwargs):
|
||||
return outvals[0]
|
||||
else:
|
||||
return outvals
|
||||
|
||||
def append(arr, values, axis=None):
|
||||
"""
|
||||
Append values to the end of an array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
arr : array_like
|
||||
Values are appended to a copy of this array.
|
||||
values : array_like
|
||||
These values are appended to a copy of `arr`. It must be of the
|
||||
correct shape (the same shape as `arr`, excluding `axis`). If
|
||||
`axis` is not specified, `values` can be any shape and will be
|
||||
flattened before use.
|
||||
axis : int, optional
|
||||
The axis along which `values` are appended. If `axis` is not
|
||||
given, both `arr` and `values` are flattened before use.
|
||||
|
||||
Returns
|
||||
-------
|
||||
append : ndarray
|
||||
A copy of `arr` with `values` appended to `axis`. Note that
|
||||
`append` does not occur in-place: a new array is allocated and
|
||||
filled. If `axis` is None, `out` is a flattened array.
|
||||
|
||||
See Also
|
||||
--------
|
||||
insert : Insert elements into an array.
|
||||
delete : Delete elements from an array.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
|
||||
array([1, 2, 3, ..., 7, 8, 9])
|
||||
|
||||
When `axis` is specified, `values` must have the correct shape.
|
||||
|
||||
>>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
|
||||
array([[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]])
|
||||
>>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: all the input arrays must have same number of dimensions, but
|
||||
the array at index 0 has 2 dimension(s) and the array at index 1 has 1
|
||||
dimension(s)
|
||||
|
||||
"""
|
||||
arr = np.asanyarray(arr)
|
||||
if axis is None:
|
||||
if arr.ndim != 1:
|
||||
arr = arr.ravel()
|
||||
values = ravel(values)
|
||||
axis = arr.ndim-1
|
||||
return np.concatenate((arr, values), axis=axis)
|
||||
|
||||
def delete(arr, obj, axis=None):
|
||||
"""
|
||||
Return a new array with sub-arrays along an axis deleted. For a one
|
||||
dimensional array, this returns those entries not returned by
|
||||
`arr[obj]`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
arr : array_like
|
||||
Input array.
|
||||
obj : slice, int or array of ints
|
||||
Indicate indices of sub-arrays to remove along the specified axis.
|
||||
|
||||
.. versionchanged:: 1.19.0
|
||||
Boolean indices are now treated as a mask of elements to remove,
|
||||
rather than being cast to the integers 0 and 1.
|
||||
|
||||
axis : int, optional
|
||||
The axis along which to delete the subarray defined by `obj`.
|
||||
If `axis` is None, `obj` is applied to the flattened array.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
A copy of `arr` with the elements specified by `obj` removed. Note
|
||||
that `delete` does not occur in-place. If `axis` is None, `out` is
|
||||
a flattened array.
|
||||
|
||||
See Also
|
||||
--------
|
||||
insert : Insert elements into an array.
|
||||
append : Append elements at the end of an array.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Often it is preferable to use a boolean mask. For example:
|
||||
|
||||
>>> arr = np.arange(12) + 1
|
||||
>>> mask = np.ones(len(arr), dtype=bool)
|
||||
>>> mask[[0,2,4]] = False
|
||||
>>> result = arr[mask,...]
|
||||
|
||||
Is equivalent to ``np.delete(arr, [0,2,4], axis=0)``, but allows further
|
||||
use of `mask`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
|
||||
>>> arr
|
||||
array([[ 1, 2, 3, 4],
|
||||
[ 5, 6, 7, 8],
|
||||
[ 9, 10, 11, 12]])
|
||||
>>> np.delete(arr, 1, 0)
|
||||
array([[ 1, 2, 3, 4],
|
||||
[ 9, 10, 11, 12]])
|
||||
|
||||
>>> np.delete(arr, np.s_[::2], 1)
|
||||
array([[ 2, 4],
|
||||
[ 6, 8],
|
||||
[10, 12]])
|
||||
>>> np.delete(arr, [1,3,5], None)
|
||||
array([ 1, 3, 5, 7, 8, 9, 10, 11, 12])
|
||||
|
||||
"""
|
||||
arr = np.asarray(arr)
|
||||
ndim = arr.ndim
|
||||
if axis is None:
|
||||
if ndim != 1:
|
||||
arr = arr.ravel()
|
||||
# needed for np.matrix, which is still not 1d after being ravelled
|
||||
ndim = arr.ndim
|
||||
axis = ndim - 1
|
||||
else:
|
||||
axis = np.normalize_axis_index(axis, ndim)
|
||||
|
||||
slobj = [slice(None)]*ndim
|
||||
N = arr.shape[axis]
|
||||
newshape = list(arr.shape)
|
||||
|
||||
if isinstance(obj, slice):
|
||||
start, stop, step = obj.indices(N)
|
||||
xr = range(start, stop, step)
|
||||
numtodel = len(xr)
|
||||
|
||||
if numtodel <= 0:
|
||||
return arr.copy()
|
||||
|
||||
# Invert if step is negative:
|
||||
if step < 0:
|
||||
step = -step
|
||||
start = xr[-1]
|
||||
stop = xr[0] + 1
|
||||
|
||||
newshape[axis] -= numtodel
|
||||
new = np.empty(newshape, arr.dtype)
|
||||
# copy initial chunk
|
||||
if start == 0:
|
||||
pass
|
||||
else:
|
||||
slobj[axis] = slice(None, start)
|
||||
new[tuple(slobj)] = arr[tuple(slobj)]
|
||||
# copy end chunk
|
||||
if stop == N:
|
||||
pass
|
||||
else:
|
||||
slobj[axis] = slice(stop-numtodel, None)
|
||||
slobj2 = [slice(None)]*ndim
|
||||
slobj2[axis] = slice(stop, None)
|
||||
new[tuple(slobj)] = arr[tuple(slobj2)]
|
||||
# copy middle pieces
|
||||
if step == 1:
|
||||
pass
|
||||
else: # use array indexing.
|
||||
keep = np.ones(stop-start, dtype=np.dtype.bool)
|
||||
keep[:stop-start:step] = False
|
||||
slobj[axis] = slice(start, stop-numtodel)
|
||||
slobj2 = [slice(None)]*ndim
|
||||
slobj2[axis] = slice(start, stop)
|
||||
arr = arr[tuple(slobj2)]
|
||||
slobj2[axis] = keep
|
||||
new[tuple(slobj)] = arr[tuple(slobj2)]
|
||||
return new
|
||||
|
||||
if isinstance(obj, int) and not isinstance(obj, bool):
|
||||
single_value = True
|
||||
else:
|
||||
single_value = False
|
||||
_obj = obj
|
||||
obj = np.asarray(obj)
|
||||
# `size == 0` to allow empty lists similar to indexing, but (as there)
|
||||
# is really too generic:
|
||||
if obj.size == 0 and not isinstance(_obj, np.NDArray):
|
||||
obj = obj.astype(np.dtype.int)
|
||||
elif obj.size == 1 and obj.dtype.kind in "ui":
|
||||
# For a size 1 integer array we can use the single-value path
|
||||
# (most dtypes, except boolean, should just fail later).
|
||||
obj = obj.item()
|
||||
single_value = True
|
||||
|
||||
if single_value:
|
||||
# optimization for a single value
|
||||
if (obj < -N or obj >= N):
|
||||
raise IndexError(
|
||||
"index %i is out of bounds for axis %i with "
|
||||
"size %i" % (obj, axis, N))
|
||||
if (obj < 0):
|
||||
obj += N
|
||||
newshape[axis] -= 1
|
||||
new = np.empty(newshape, arr.dtype,)
|
||||
slobj[axis] = slice(None, obj)
|
||||
new[tuple(slobj)] = arr[tuple(slobj)]
|
||||
slobj[axis] = slice(obj, None)
|
||||
slobj2 = [slice(None)]*ndim
|
||||
slobj2[axis] = slice(obj+1, None)
|
||||
new[tuple(slobj)] = arr[tuple(slobj2)]
|
||||
else:
|
||||
if obj.dtype == np.dtype.bool:
|
||||
if obj.shape != (N,):
|
||||
raise ValueError('boolean array argument obj to delete '
|
||||
'must be one dimensional and match the axis '
|
||||
'length of {}'.format(N))
|
||||
|
||||
# optimization, the other branch is slower
|
||||
keep = ~obj
|
||||
else:
|
||||
keep = np.ones(N, dtype=np.dtype.bool)
|
||||
keep[obj,] = False
|
||||
|
||||
slobj[axis] = keep
|
||||
new = arr[tuple(slobj)]
|
||||
|
||||
return new
|
||||
|
||||
def insert(arr, obj, values, axis=None):
|
||||
"""
|
||||
Insert values along the given axis before the given indices.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
arr : array_like
|
||||
Input array.
|
||||
obj : int, slice or sequence of ints
|
||||
Object that defines the index or indices before which `values` is
|
||||
inserted.
|
||||
|
||||
Support for multiple insertions when `obj` is a single scalar or a
|
||||
sequence with one element (similar to calling insert multiple
|
||||
times).
|
||||
values : array_like
|
||||
Values to insert into `arr`. If the type of `values` is different
|
||||
from that of `arr`, `values` is converted to the type of `arr`.
|
||||
`values` should be shaped so that ``arr[...,obj,...] = values``
|
||||
is legal.
|
||||
axis : int, optional
|
||||
Axis along which to insert `values`. If `axis` is None then `arr`
|
||||
is flattened first.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
A copy of `arr` with `values` inserted. Note that `insert`
|
||||
does not occur in-place: a new array is returned. If
|
||||
`axis` is None, `out` is a flattened array.
|
||||
|
||||
See Also
|
||||
--------
|
||||
append : Append elements at the end of an array.
|
||||
concatenate : Join a sequence of arrays along an existing axis.
|
||||
delete : Delete elements from an array.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Note that for higher dimensional inserts ``obj=0`` behaves very different
|
||||
from ``obj=[0]`` just like ``arr[:,0,:] = values`` is different from
|
||||
``arr[:,[0],:] = values``.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> a = np.array([[1, 1], [2, 2], [3, 3]])
|
||||
>>> a
|
||||
array([[1, 1],
|
||||
[2, 2],
|
||||
[3, 3]])
|
||||
>>> np.insert(a, 1, 5)
|
||||
array([1, 5, 1, ..., 2, 3, 3])
|
||||
>>> np.insert(a, 1, 5, axis=1)
|
||||
array([[1, 5, 1],
|
||||
[2, 5, 2],
|
||||
[3, 5, 3]])
|
||||
|
||||
Difference between sequence and scalars:
|
||||
|
||||
>>> np.insert(a, [1], [[1],[2],[3]], axis=1)
|
||||
array([[1, 1, 1],
|
||||
[2, 2, 2],
|
||||
[3, 3, 3]])
|
||||
>>> np.array_equal(np.insert(a, 1, [1, 2, 3], axis=1),
|
||||
... np.insert(a, [1], [[1],[2],[3]], axis=1))
|
||||
True
|
||||
|
||||
>>> b = a.flatten()
|
||||
>>> b
|
||||
array([1, 1, 2, 2, 3, 3])
|
||||
>>> np.insert(b, [2, 2], [5, 6])
|
||||
array([1, 1, 5, ..., 2, 3, 3])
|
||||
|
||||
>>> np.insert(b, slice(2, 4), [5, 6])
|
||||
array([1, 1, 5, ..., 2, 3, 3])
|
||||
|
||||
>>> np.insert(b, [2, 2], [7.13, False]) # type casting
|
||||
array([1, 1, 7, ..., 2, 3, 3])
|
||||
|
||||
>>> x = np.arange(8).reshape(2, 4)
|
||||
>>> idx = (1, 3)
|
||||
>>> np.insert(x, idx, 999, axis=1)
|
||||
array([[ 0, 999, 1, 2, 999, 3],
|
||||
[ 4, 999, 5, 6, 999, 7]])
|
||||
|
||||
"""
|
||||
arr = np.asarray(arr)
|
||||
ndim = arr.ndim
|
||||
if axis is None:
|
||||
if ndim != 1:
|
||||
arr = arr.ravel()
|
||||
# needed for np.matrix, which is still not 1d after being ravelled
|
||||
ndim = arr.ndim
|
||||
axis = ndim - 1
|
||||
else:
|
||||
axis = np.normalize_axis_index(axis, ndim)
|
||||
slobj = [slice(None)]*ndim
|
||||
N = arr.shape[axis]
|
||||
newshape = list(arr.shape)
|
||||
|
||||
if isinstance(obj, slice):
|
||||
# turn it into a range object
|
||||
indices = np.arange(*obj.indices(N), dtype=np.dtype.int)
|
||||
else:
|
||||
# need to copy obj, because indices will be changed in-place
|
||||
indices = np.array(obj).copy()
|
||||
if indices.dtype == np.dtype.bool:
|
||||
# See also delete
|
||||
warnings.warn(
|
||||
"in the future insert will treat boolean arrays and "
|
||||
"array-likes as a boolean index instead of casting it to "
|
||||
"integer", FutureWarning, stacklevel=2)
|
||||
indices = indices.astype(np.dtype.int)
|
||||
elif indices.ndim > 1:
|
||||
raise ValueError(
|
||||
"index array argument obj to insert must be one dimensional "
|
||||
"or scalar")
|
||||
if indices.size == 1:
|
||||
index = indices.item()
|
||||
if index < -N or index > N:
|
||||
raise IndexError("index {} is out of bounds for axis {} with size {}".
|
||||
format(obj, axis, N))
|
||||
if (index < 0):
|
||||
index += N
|
||||
|
||||
# There are some object array corner cases here, but we cannot avoid
|
||||
# that:
|
||||
values = np.array(values, copy=False, ndmin=arr.ndim, dtype=arr.dtype)
|
||||
if indices.ndim == 0:
|
||||
# broadcasting is very different here, since a[:,0,:] = ... behaves
|
||||
# very different from a[:,[0],:] = ...! This changes values so that
|
||||
# it works likes the second case. (here a[:,0:1,:])
|
||||
values = np.moveaxis(values, 0, axis)
|
||||
numnew = values.shape[axis]
|
||||
newshape[axis] += numnew
|
||||
new = np.empty(newshape, arr.dtype,)
|
||||
slobj[axis] = slice(None, index)
|
||||
new[tuple(slobj)] = arr[tuple(slobj)]
|
||||
slobj[axis] = slice(index, index+numnew)
|
||||
new[tuple(slobj)] = values
|
||||
slobj[axis] = slice(index+numnew, None)
|
||||
slobj2 = [slice(None)] * ndim
|
||||
slobj2[axis] = slice(index, None)
|
||||
new[tuple(slobj)] = arr[tuple(slobj2)]
|
||||
return new
|
||||
elif indices.size == 0 and not isinstance(obj, np.NDArray):
|
||||
# Can safely cast the empty list to intp
|
||||
indices = indices.astype(np.dtype.int)
|
||||
|
||||
indices[indices < 0] += N
|
||||
|
||||
numnew = len(indices)
|
||||
#order = indices.argsort(kind='mergesort') # stable sort
|
||||
order = np.argsort(indices)
|
||||
indices[order] += np.arange(numnew)
|
||||
|
||||
newshape[axis] += numnew
|
||||
old_mask = np.ones(newshape[axis], dtype=np.dtype.bool)
|
||||
old_mask[indices] = False
|
||||
|
||||
new = np.empty(newshape, arr.dtype)
|
||||
slobj2 = [slice(None)]*ndim
|
||||
slobj[axis] = indices
|
||||
slobj2[axis] = old_mask
|
||||
new[tuple(slobj)] = values
|
||||
new[tuple(slobj2)] = arr
|
||||
|
||||
return new
|
||||
|
||||
Binary file not shown.
@ -183,8 +183,12 @@ def getcolors(cs, alpha=None):
|
||||
if isinstance(cs[0], int):
|
||||
colors.append(getcolor(cs, alpha))
|
||||
else:
|
||||
for c in cs:
|
||||
colors.append(getcolor(c, alpha))
|
||||
if isinstance(alpha, (tuple, list)):
|
||||
for c, a in zip(cs, alpha):
|
||||
colors.append(getcolor(c, a))
|
||||
else:
|
||||
for c in cs:
|
||||
colors.append(getcolor(c, alpha))
|
||||
else:
|
||||
colors.append(getcolor(cs, alpha))
|
||||
return colors
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
package org.meteoinfo.math.sort;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class MergeSort {
|
||||
|
||||
/**
|
||||
* Merge sort
|
||||
* @param sourceArray Source array
|
||||
* @return Sorted array
|
||||
* @throws Exception
|
||||
*/
|
||||
public int[] sort(int[] sourceArray) throws Exception {
|
||||
// 对 arr 进行拷贝,不改变参数内容
|
||||
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
|
||||
|
||||
if (arr.length < 2) {
|
||||
return arr;
|
||||
}
|
||||
int middle = (int) Math.floor(arr.length / 2);
|
||||
|
||||
int[] left = Arrays.copyOfRange(arr, 0, middle);
|
||||
int[] right = Arrays.copyOfRange(arr, middle, arr.length);
|
||||
|
||||
return merge(sort(left), sort(right));
|
||||
}
|
||||
|
||||
protected int[] merge(int[] left, int[] right) {
|
||||
int[] result = new int[left.length + right.length];
|
||||
int i = 0;
|
||||
while (left.length > 0 && right.length > 0) {
|
||||
if (left[0] <= right[0]) {
|
||||
result[i++] = left[0];
|
||||
left = Arrays.copyOfRange(left, 1, left.length);
|
||||
} else {
|
||||
result[i++] = right[0];
|
||||
right = Arrays.copyOfRange(right, 1, right.length);
|
||||
}
|
||||
}
|
||||
|
||||
while (left.length > 0) {
|
||||
result[i++] = left[0];
|
||||
left = Arrays.copyOfRange(left, 1, left.length);
|
||||
}
|
||||
|
||||
while (right.length > 0) {
|
||||
result[i++] = right[0];
|
||||
right = Arrays.copyOfRange(right, 1, right.length);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ import java.util.Comparator;
|
||||
* always appear before S in the sorted list.
|
||||
* <p>
|
||||
* For speed of execution, we implement it without recursion. Instead,
|
||||
* we requires an auxiliary array (stack) of storage, of length
|
||||
* we require an auxiliary array (stack) of storage, of length
|
||||
* 2 log<sub><small>2</small></sub> n. When a subarray has gotten down to size 7,
|
||||
* we sort it by straight insertion.
|
||||
*
|
||||
|
||||
@ -305,7 +305,11 @@ public class ArrayBoolean extends Array {
|
||||
}
|
||||
|
||||
public void setObject(Index i, Object value) {
|
||||
storage[i.currentElement()] = (Boolean) value;
|
||||
if (value instanceof Integer) {
|
||||
storage[i.currentElement()] = ((Integer) value == 1);
|
||||
} else {
|
||||
storage[i.currentElement()] = (Boolean) value;
|
||||
}
|
||||
}
|
||||
|
||||
// package private : mostly for iterators
|
||||
|
||||
@ -275,7 +275,11 @@ public class ArrayDouble extends Array {
|
||||
}
|
||||
|
||||
public void setObject(Index i, Object value) {
|
||||
storageD[i.currentElement()] = ((Number) value).doubleValue();
|
||||
if (value instanceof Boolean) {
|
||||
storageD[i.currentElement()] = ((Boolean) value) ? 1 : 0;
|
||||
} else {
|
||||
storageD[i.currentElement()] = ((Number) value).doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
// trusted, assumes that individual dimension lengths have been checked
|
||||
@ -368,7 +372,11 @@ public class ArrayDouble extends Array {
|
||||
}
|
||||
|
||||
public void setObject(int index, Object value) {
|
||||
storageD[index] = ((Number) value).doubleValue();
|
||||
if (value instanceof Boolean) {
|
||||
storageD[index] = ((Boolean) value) ? 1 : 0;
|
||||
} else {
|
||||
storageD[index] = ((Number) value).doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -298,7 +298,11 @@ public class ArrayInt extends Array {
|
||||
}
|
||||
|
||||
public void setObject(Index i, Object value) {
|
||||
storage[i.currentElement()] = ((Number) value).intValue();
|
||||
if (value instanceof Boolean) {
|
||||
storage[i.currentElement()] = ((Boolean) value) ? 1 : 0;
|
||||
} else {
|
||||
storage[i.currentElement()] = ((Number) value).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
// package private : mostly for iterators
|
||||
@ -397,7 +401,11 @@ public class ArrayInt extends Array {
|
||||
}
|
||||
|
||||
public void setObject(int index, Object value) {
|
||||
storage[index] = ((Number) value).intValue();
|
||||
if (value instanceof Boolean) {
|
||||
storage[index] = ((Boolean) value) ? 1 : 0;
|
||||
} else {
|
||||
storage[index] = ((Number) value).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -672,6 +672,18 @@ public class Index implements Cloneable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current element's index. General-rank case.
|
||||
*
|
||||
* @param index set current value to these values
|
||||
* @return this, so you can use A.get(i.set(i))
|
||||
* @throws ArrayIndexOutOfBoundsException if index.length != rank.
|
||||
*/
|
||||
public Index set(List<Integer> indexList) {
|
||||
int[] index = indexList.stream().mapToInt(Integer::intValue).toArray();
|
||||
return set(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* set current element at dimension dim to v
|
||||
*
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package org.meteoinfo.ndarray;
|
||||
|
||||
import org.meteoinfo.ndarray.math.ArrayUtil;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MixIterator implements IndexIterator {
|
||||
@ -29,7 +32,21 @@ public class MixIterator implements IndexIterator {
|
||||
if (range instanceof Range) {
|
||||
shape[i] = ((Range) range).length();
|
||||
} else {
|
||||
shape[i] = ((List) range).size();
|
||||
Array arr = (Array) range;
|
||||
if (arr.getDataType() == DataType.BOOLEAN) {
|
||||
List<Integer> tList = new ArrayList<>();
|
||||
IndexIterator iter = arr.getIndexIterator();
|
||||
int j = 0;
|
||||
while (iter.hasNext()) {
|
||||
if (iter.getBooleanNext()) {
|
||||
tList.add(j);
|
||||
}
|
||||
j += 1;
|
||||
}
|
||||
arr = ArrayUtil.array_list(tList, DataType.INT);
|
||||
this.ranges.set(i, arr);
|
||||
}
|
||||
shape[i] = (int) arr.getSize();
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
@ -297,9 +314,9 @@ public class MixIterator implements IndexIterator {
|
||||
int c;
|
||||
for (Object range : this.ranges) {
|
||||
if (range instanceof Range) {
|
||||
c = ((Range)range).elementNC(rangeCounter[i]);
|
||||
c = ((Range) range).elementNC(rangeCounter[i]);
|
||||
} else {
|
||||
c = ((List<Integer>)range).get(rangeCounter[i]);
|
||||
c = ((Array) range).getInt(rangeCounter[i]);
|
||||
}
|
||||
currentCounter[i] = c;
|
||||
i += 1;
|
||||
|
||||
@ -6022,11 +6022,11 @@ public class ArrayMath {
|
||||
public static Array setSection(Array a, List<Range> ranges, Array v) throws InvalidRangeException {
|
||||
Array r = a.section(ranges);
|
||||
IndexIterator iter = r.getIndexIterator();
|
||||
if (r.getSize() != v.getSize()) {
|
||||
/*if (r.getSize() != v.getSize()) {
|
||||
if (r.getShape() != v.getShape()) {
|
||||
v = ArrayUtil.broadcast(v, r.getShape());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
Index index = v.getIndex();
|
||||
while (iter.hasNext()) {
|
||||
iter.setObjectNext(v.getObject(index));
|
||||
@ -6207,18 +6207,34 @@ public class ArrayMath {
|
||||
* @param v Number value
|
||||
* @return Result array
|
||||
*/
|
||||
public static Array setSection_List(Array a, List<List<Integer>> ranges, Number v) {
|
||||
public static Array setSection_List(Array a, List<Array> ranges, Number v) {
|
||||
//Array r = copy(a);
|
||||
int n = a.getRank();
|
||||
int[] count = new int[n];
|
||||
Index index = a.getIndex();
|
||||
int m = ranges.get(0).size();
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
count[j] = ranges.get(j).get(i);
|
||||
int m = (int) ranges.get(0).getSize();
|
||||
if (ranges.get(0).getDataType() == DataType.BOOLEAN) {
|
||||
for (int i = 0; i < m; i++) {
|
||||
boolean bool = true;
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (!ranges.get(j).getBoolean(i)) {
|
||||
bool = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bool) {
|
||||
a.setObject(index, v);
|
||||
}
|
||||
index.incr();
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
count[j] = ranges.get(j).getInt(i);
|
||||
}
|
||||
index.set(count);
|
||||
a.setObject(index, v);
|
||||
}
|
||||
index.set(count);
|
||||
a.setObject(index, v);
|
||||
}
|
||||
|
||||
return a;
|
||||
@ -6232,20 +6248,37 @@ public class ArrayMath {
|
||||
* @param v Array value
|
||||
* @return Result array
|
||||
*/
|
||||
public static Array setSection_List(Array a, List<List<Integer>> ranges, Array v) {
|
||||
public static Array setSection_List(Array a, List<Array> ranges, Array v) {
|
||||
//Array r = copy(a);
|
||||
int n = a.getRank();
|
||||
int[] count = new int[n];
|
||||
Index index = a.getIndex();
|
||||
Index vIndex = v.getIndex();
|
||||
int m = ranges.get(0).size();
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
count[j] = ranges.get(j).get(i);
|
||||
int m = (int) ranges.get(0).getSize();
|
||||
if (ranges.get(0).getDataType() == DataType.BOOLEAN) {
|
||||
for (int i = 0; i < m; i++) {
|
||||
boolean bool = true;
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (!ranges.get(j).getBoolean(i)) {
|
||||
bool = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bool) {
|
||||
a.setObject(index, v.getObject(vIndex));
|
||||
vIndex.incr();
|
||||
}
|
||||
index.incr();
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
count[j] = ranges.get(j).getInt(i);
|
||||
}
|
||||
index.set(count);
|
||||
a.setObject(index, v.getObject(vIndex));
|
||||
vIndex.incr();
|
||||
}
|
||||
index.set(count);
|
||||
a.setObject(index, v.getObject(vIndex));
|
||||
vIndex.incr();
|
||||
}
|
||||
|
||||
return a;
|
||||
|
||||
@ -1633,6 +1633,12 @@ public class ArrayUtil {
|
||||
StringBuilder sbuff = new StringBuilder();
|
||||
sbuff.append("array(");
|
||||
int ndim = a.getRank();
|
||||
if (ndim == 0) {
|
||||
sbuff.append(a.getObject(0));
|
||||
sbuff.append(")");
|
||||
return sbuff.toString();
|
||||
}
|
||||
|
||||
if (ndim > 1) {
|
||||
for (int i = 0; i < ndim - 1; i++)
|
||||
sbuff.append("[");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user