add flat attribute in NDArray

This commit is contained in:
wyq 2021-04-14 21:11:41 +08:00
parent ec73b697cb
commit bcf409cf43
6 changed files with 263 additions and 30 deletions

View File

@ -1,11 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\grads">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
<RecentFolder Folder="D:\Run\emips\run_meic"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\calipso"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\array">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\FY"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\himawari"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\modis"/>
@ -14,21 +9,26 @@
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\hdf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\grads"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\toolbox"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\toolbox\miml"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\toolbox\miml\cluster"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contourf_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\toolbox\miml\deep_learning\classification\moon.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_minutes.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\grads\test_contour.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\toolbox\miml\cluster\xmeans_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\array\flat.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contourf_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\toolbox\miml\deep_learning\classification\moon.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_minutes.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\grads\test_contour.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\toolbox\miml\cluster\xmeans_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\array\flat.py"/>
</RecentFiles>
</File>
<Font>
@ -36,5 +36,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-4,2" MainFormSize="1361,774"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,693"/>
</MeteoInfo>

View File

@ -0,0 +1,52 @@
from org.meteoinfo.ndarray import FlatIndex
from org.meteoinfo.ndarray.math import ArrayUtil
class flatiter(object):
def __init__(self, array):
self.array = array
self.flat_index = FlatIndex(array._array)
self.size = self.array.size
def __iter__(self):
return self
def next(self):
return self.array.next()
def __getitem__(self, key):
if isinstance(key, int):
return self.flat_index.getObject(key)
elif isinstance(key, slice):
sidx = 0 if key.start is None else key.start
if sidx < 0:
sidx = self.size + sidx
eidx = self.size if key.stop is None else key.stop
if eidx < 0:
eidx = self.size + eidx
eidx -= 1
step = 1 if key.step is None else key.step
r = self.flat_index.section(sidx, eidx, step)
return asarray(r)
else:
r = self.flat_index.section(key)
return asarray(r)
def __setitem__(self, key, value):
if isinstance(value, (list, tuple)):
value = ArrayUtil.array(value, None)
if isinstance(key, int):
return self.flat_index.setSection(key, value)
elif isinstance(key, slice):
sidx = 0 if key.start is None else key.start
if sidx < 0:
sidx = self.size + sidx
eidx = self.size if key.stop is None else key.stop
if eidx < 0:
eidx = self.size + eidx
eidx -= 1
step = 1 if key.step is None else key.step
self.flat_index.setSection(sidx, eidx, step, value)
else:
self.flat_index.setSection(key, value)

View File

@ -10,6 +10,7 @@ from org.meteoinfo.ndarray import Array, Range, MAMath, Complex, Dimension
import datetime
import _dtype
from ._base import flatiter
# The encapsulate class of Array
class NDArray(object):
@ -20,10 +21,7 @@ class NDArray(object):
self._array = array
self.ndim = array.getRank()
s = array.getShape()
s1 = []
for i in range(len(s)):
s1.append(s[i])
self._shape = tuple(s1)
self._shape = tuple(s)
self.dtype = _dtype.dtype.fromjava(array.getDataType())
self.size = int(self._array.getSize())
self.iterator = array.getIndexIterator()
@ -51,7 +49,7 @@ class NDArray(object):
nvalue[idx] = int(self._array.getSize() / l)
value = tuple(nvalue)
self._shape = value
self.__init__(self._array.reshape(value))
self.__init__(self._array.reshapeNoCopy(value))
shape = property(get_shape, set_shape)
@ -82,7 +80,7 @@ class NDArray(object):
if len(indices) < self.ndim:
if isinstance(indices, tuple):
indices = list(indices)
for i in range(self.ndim - len(indices)):
for _ in range(self.ndim - len(indices)):
indices.append(slice(None))
allint = True
@ -299,6 +297,7 @@ class NDArray(object):
else:
r = ArrayMath.setSection_Mix(self._array, ranges, value)
self._array = r
self.iterator = self._array.getIndexIterator()
def __value_other(self, other):
if isinstance(other, NDArray):
@ -437,8 +436,6 @@ class NDArray(object):
"""
provide iteration over the values of the array
"""
#self.idx = -1
self.iterator = self._array.getIndexIterator()
return self
def next(self):
@ -446,10 +443,6 @@ class NDArray(object):
return self.iterator.getObjectNext()
else:
raise StopIteration()
# self.idx += 1
# if self.idx >= self.size:
# raise StopIteration()
# return self._array.getObject(self.idx)
def copy(self):
'''
@ -524,7 +517,7 @@ class NDArray(object):
'''
return ArrayMath.containsNaN(self._array)
def getsize(self):
def getsize(self, name='size'):
if name == 'size':
sizestr = str(self.shape[0])
if self.ndim > 1:
@ -868,7 +861,7 @@ class NDArray(object):
if not idx is None:
shape[idx] = self.size / n
r = NDArray(self._array.reshape(shape))
r = NDArray(self._array.reshapeNoCopy(shape))
r.base = self.get_base()
return r
@ -930,13 +923,30 @@ class NDArray(object):
I = property(inv)
@property
def flat(self):
"""
A 1-D iterator over the array.
:return: 1-D iterator over the array.
"""
return flatiter(self)
@flat.setter
def flat(self, value):
"""
flat setter.
:param value: The setting value.
"""
self.flat[:] = value
def flatten(self):
'''
Return a copy of the array collapsed into one dimension.
:returns: (*NDArray*) A copy of the input array, flattened to one dimension.
'''
r = self.reshape(int(self._array.getSize()))
shape = [self.size]
r = NDArray(self._array.reshape(shape))
return r
def ravel(self):
@ -945,7 +955,8 @@ class NDArray(object):
:returns: (*NDArray*) A copy of the input array, flattened to one dimension.
'''
r = self.reshape(int(self._array.getSize()))
shape = [self.size]
r = NDArray(self._array.reshape(shape))
return r
def repeat(self, repeats, axis=None):

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="config.xml" Type="configurefile">
<Path OpenPath="D:\Temp\HYSPLIT"/>
<Path OpenPath="D:\Temp\traj\Sample"/>
<Font>
<TextFont FontName="YaHei Consolas Hybrid" FontSize="14"/>
<LegendFont FontName="宋体" FontSize="12"/>
@ -8,5 +8,5 @@
<ScriptLanguage Language="Jython"/>
<LookFeel LafDecorated="true" Name="FlatLightLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-6,2" MainFormSize="1293,693" ShowMeteoDataDlg="true"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,693" ShowMeteoDataDlg="false"/>
</MeteoInfo>

View File

@ -0,0 +1,148 @@
package org.meteoinfo.ndarray;
import java.util.List;
public class FlatIndex {
private Array array;
private Index index;
/**
* Constructor
* @param array The array
*/
public FlatIndex(Array array) {
this.array = array;
this.index = this.array.getIndex();
}
/**
* Get object
* @param idx The flat index
* @return The object
*/
public Object getObject(int idx) {
this.index.setCurrentIndex(idx);
return this.array.getObject(this.index);
}
/**
* Set object
* @param idx The flat index
* @param value The object
*/
public void setObject(int idx, Object value) {
this.index.setCurrentIndex(idx);
this.array.setObject(this.index, value);
}
/**
* Get section array
* @param first The first index
* @param last The last index
* @param stride The stride
* @return Array
*/
public Array section(int first, int last, int stride) {
int n = 1 + Math.abs(last - first) / Math.abs(stride);
Array r = Array.factory(this.array.dataType, new int[]{n});
int ii = 0;
if (last >= first) {
for (int i = first; i <= last; i += stride) {
index.setCurrentIndex(i);
r.setObject(ii, this.array.getObject(index));
ii += 1;
}
} else {
for (int i = first; i >= last; i += stride) {
index.setCurrentIndex(i);
r.setObject(ii, this.array.getObject(index));
ii += 1;
}
}
return r;
}
/**
* Set section array
* @param idx Index list
* @return Section array
*/
public Array section(List<Integer> idx) {
Array r = Array.factory(this.array.dataType, new int[]{idx.size()});
int ii = 0;
for (int i : idx) {
this.index.setCurrentIndex(i);
r.setObject(ii, this.array.getObject(this.index));
ii += 1;
}
return r;
}
/**
* Set section array
* @param first The first index
* @param last The last index
* @param stride The stride
* @param value The value
*/
public void setSection(int first, int last, int stride, Object value) {
if (last >= first) {
for (int i = first; i <= last; i += stride) {
index.setCurrentIndex(i);
this.array.setObject(index, value);
}
} else {
for (int i = first; i >= last; i += stride) {
index.setCurrentIndex(i);
this.array.setObject(index, value);
}
}
}
/**
* Set section array
* @param first The first index
* @param last The last index
* @param stride The stride
* @param value The value array
*/
public void setSection(int first, int last, int stride, Array value) {
IndexIterator iterator = value.getIndexIterator();
if (last >= first) {
for (int i = first; i <= last; i += stride) {
index.setCurrentIndex(i);
this.array.setObject(index, iterator.getObjectNext());
}
} else {
for (int i = first; i >= last; i += stride) {
index.setCurrentIndex(i);
this.array.setObject(index, iterator.getObjectNext());
}
}
}
/**
* Set section
* @param idx Index list
* @param value Value
*/
public void setSection(List<Integer> idx, Object value) {
for (int i : idx) {
this.index.setCurrentIndex(i);
this.array.setObject(index, value);
}
}
/**
* Set section
* @param idx Index list
* @param value Value array
*/
public void setSection(List<Integer>idx, Array value) {
IndexIterator iterator = value.getIndexIterator();
for (int i : idx) {
this.index.setCurrentIndex(i);
this.array.setObject(index, iterator.getObjectNext());
}
}
}

View File

@ -581,6 +581,28 @@ public class Index implements Cloneable {
set(current); // transfer to subclass fields
}
/**
* Set the current index from the 1D "current index" currIndex =
* stride[0]*current[0] + ...
*
* @param currIndex set to this value
*/
public void setCurrentIndex(int currIndex) {
int[] cc = new int[rank];
int len;
for (int ii = 0; ii < rank; ii++) { // general rank
len = 1;
for (int i = ii + 1; i < rank; i++) {
len *= shape[i];
}
cc[ii] = currIndex / len;
currIndex -= len * cc[ii];
if (currIndex == 0)
break;
}
set(cc); // transfer to subclass fields
}
/**
* Increment the current element by 1. Used by IndexIterator. General rank,
* with subclass specialization. Vlen skipped.