|
25 | 25 | cos, |
26 | 26 | digitize, |
27 | 27 | empty, |
| 28 | + errstate, |
28 | 29 | floor, |
29 | 30 | histogram, |
30 | 31 | histogram2d, |
@@ -119,6 +120,7 @@ class EddiesObservations(object): |
119 | 120 | "observations", |
120 | 121 | "sign_type", |
121 | 122 | "raw_data", |
| 123 | + "period_", |
122 | 124 | ) |
123 | 125 |
|
124 | 126 | ELEMENTS = [ |
@@ -150,6 +152,7 @@ def __init__( |
150 | 152 | only_variables=None, |
151 | 153 | raw_data=False, |
152 | 154 | ): |
| 155 | + self.period_ = None |
153 | 156 | self.only_variables = only_variables |
154 | 157 | self.raw_data = raw_data |
155 | 158 | self.track_extra_variables = ( |
@@ -1686,65 +1689,89 @@ def filled( |
1686 | 1689 | c.norm = Normalize(vmin=vmin, vmax=vmax) |
1687 | 1690 | return c |
1688 | 1691 |
|
1689 | | - def merge_indexs(self, filter, index=None): |
| 1692 | + def __merge_filters__(self, *filters): |
1690 | 1693 | """ |
1691 | | - Compute an intersectin between indexs and filters after to evaluate each of them |
| 1694 | + Compute an intersection between all filters after to evaluate each of them |
1692 | 1695 |
|
1693 | | - :param callable,None,slice,array[int],array[bool] filter: |
1694 | | - :param callable,None,slice,array[int],array[bool] index: |
| 1696 | + :param list(slice,array[int],array[bool]) filters: |
1695 | 1697 |
|
1696 | 1698 | :return: Return applicable object to numpy.array |
1697 | 1699 | :rtype: slice, index, mask |
1698 | 1700 | """ |
1699 | | - # If filter is a function we apply on dataset |
1700 | | - if callable(filter): |
1701 | | - filter = filter(self) |
1702 | | - # Solve indexs case |
1703 | | - if index is not None: |
1704 | | - index = self.merge_indexs(index) |
| 1701 | + filter1 = filters[0] |
| 1702 | + if len(filters) > 2: |
| 1703 | + filter2 = self.__merge_filters__(*filters[1:]) |
| 1704 | + elif len(filters) == 2: |
| 1705 | + filter2 = filters[1] |
1705 | 1706 | # Merge indexs and filter |
1706 | | - if index is None and filter is None: |
1707 | | - return slice(None) |
1708 | | - if index is None: |
1709 | | - return filter |
1710 | | - if filter is None: |
1711 | | - return index |
1712 | | - if isinstance(index, slice): |
| 1707 | + if isinstance(filter1, slice): |
1713 | 1708 | reject = ones(len(self), dtype="bool") |
1714 | | - reject[index] = False |
1715 | | - if isinstance(filter, slice): |
1716 | | - reject[filter] = False |
| 1709 | + reject[filter1] = False |
| 1710 | + if isinstance(filter2, slice): |
| 1711 | + reject[filter2] = False |
1717 | 1712 | return ~reject |
1718 | 1713 | # Mask case |
1719 | | - elif filter.dtype == bool: |
1720 | | - return ~reject * filter |
| 1714 | + elif filter2.dtype == bool: |
| 1715 | + return ~reject * filter2 |
1721 | 1716 | # index case |
1722 | 1717 | else: |
1723 | | - return filter[~reject[filter]] |
| 1718 | + return filter2[~reject[filter2]] |
1724 | 1719 | # mask case |
1725 | | - elif index.dtype == bool: |
1726 | | - if isinstance(filter, slice): |
| 1720 | + elif filter1.dtype == bool: |
| 1721 | + if isinstance(filter2, slice): |
1727 | 1722 | select = zeros(len(self), dtype="bool") |
1728 | | - select[filter] = True |
1729 | | - return select * index |
| 1723 | + select[filter2] = True |
| 1724 | + return select * filter1 |
1730 | 1725 | # Mask case |
1731 | | - elif filter.dtype == bool: |
1732 | | - return filter * index |
| 1726 | + elif filter2.dtype == bool: |
| 1727 | + return filter2 * filter1 |
1733 | 1728 | # index case |
1734 | 1729 | else: |
1735 | | - return filter[index[filter]] |
| 1730 | + return filter2[filter1[filter2]] |
1736 | 1731 | # index case |
1737 | 1732 | else: |
1738 | | - if isinstance(filter, slice): |
| 1733 | + if isinstance(filter2, slice): |
1739 | 1734 | select = zeros(len(self), dtype="bool") |
1740 | | - select[filter] = True |
1741 | | - return index[select[index]] |
| 1735 | + select[filter2] = True |
| 1736 | + return filter1[select[filter1]] |
1742 | 1737 | # Mask case |
1743 | | - elif filter.dtype == bool: |
1744 | | - return index[filter[index]] |
| 1738 | + elif filter2.dtype == bool: |
| 1739 | + return filter1[filter2[filter1]] |
1745 | 1740 | # index case |
1746 | 1741 | else: |
1747 | | - return index[in1d(index, filter)] |
| 1742 | + return filter1[in1d(filter1, filter2)] |
| 1743 | + |
| 1744 | + def merge_filters(self, *filters): |
| 1745 | + """ |
| 1746 | + Compute an intersection between all filters after to evaluate each of them |
| 1747 | +
|
| 1748 | + :param list(callable,None,slice,array[int],array[bool]) filters: |
| 1749 | +
|
| 1750 | + :return: Return applicable object to numpy.array |
| 1751 | + :rtype: slice, index, mask |
| 1752 | + """ |
| 1753 | + filters_ = list() |
| 1754 | + # Remove all filter which select all obs |
| 1755 | + for filter in filters: |
| 1756 | + if callable(filter): |
| 1757 | + filter = filter(self) |
| 1758 | + if filter is None: |
| 1759 | + continue |
| 1760 | + if isinstance(filter, slice): |
| 1761 | + if slice(None) == slice(None): |
| 1762 | + continue |
| 1763 | + if filter.dtype == "bool": |
| 1764 | + if filter.all(): |
| 1765 | + continue |
| 1766 | + if not filter.any(): |
| 1767 | + return empty(0, dtype=int) |
| 1768 | + filters_.append(filter) |
| 1769 | + if len(filters_) == 1: |
| 1770 | + return filters_[0] |
| 1771 | + elif len(filters_) == 0: |
| 1772 | + return slice(None) |
| 1773 | + else: |
| 1774 | + return self.__merge_filters__(*filters_) |
1748 | 1775 |
|
1749 | 1776 | def bins_stat(self, xname, bins=None, yname=None, method=None, mask=None): |
1750 | 1777 | """ |
@@ -1891,7 +1918,6 @@ def grid_count(self, bins, intern=False, center=False): |
1891 | 1918 | grid.mask = grid.data == 0 |
1892 | 1919 | else: |
1893 | 1920 | x_ref = ((self.longitude - x0) % 360 + x0 - 180).reshape(-1, 1) |
1894 | | - # x, y = (self[x_name] - x_ref) % 360 + x_ref, self[y_name] |
1895 | 1921 | nb = x_ref.shape[0] |
1896 | 1922 | for i_, (x, y_) in enumerate(zip(self[x_name], self[y_name])): |
1897 | 1923 | x_ = (x - x_ref[i_]) % 360 + x_ref[i_] |
@@ -1974,15 +2000,16 @@ def grid_stat(self, bins, varname, data=None): |
1974 | 2000 | nb_obs = histogram2d(x, y, (x_bins, y_bins))[0] |
1975 | 2001 | from ..dataset.grid import RegularGridDataset |
1976 | 2002 |
|
1977 | | - regular_grid = RegularGridDataset.with_array( |
1978 | | - coordinates=("x", "y"), |
1979 | | - datas={ |
1980 | | - varname: ma.array(sum_obs / nb_obs, mask=nb_obs == 0), |
1981 | | - "x": x_bins[:-1], |
1982 | | - "y": y_bins[:-1], |
1983 | | - }, |
1984 | | - centered=False, |
1985 | | - ) |
| 2003 | + with errstate(divide="ignore", invalid="ignore"): |
| 2004 | + regular_grid = RegularGridDataset.with_array( |
| 2005 | + coordinates=("x", "y"), |
| 2006 | + datas={ |
| 2007 | + varname: ma.array(sum_obs / nb_obs, mask=nb_obs == 0), |
| 2008 | + "x": x_bins[:-1], |
| 2009 | + "y": y_bins[:-1], |
| 2010 | + }, |
| 2011 | + centered=False, |
| 2012 | + ) |
1986 | 2013 | return regular_grid |
1987 | 2014 |
|
1988 | 2015 | def interp_grid( |
@@ -2030,7 +2057,18 @@ def period(self): |
2030 | 2057 | :return: first and last date |
2031 | 2058 | :rtype: (int,int) |
2032 | 2059 | """ |
2033 | | - return self.time.min(), self.time.max() |
| 2060 | + if self.period_ is None: |
| 2061 | + self.period_ = self.time.min(), self.time.max() |
| 2062 | + return self.period_ |
| 2063 | + |
| 2064 | + @property |
| 2065 | + def nb_days(self): |
| 2066 | + """Return period days cover by dataset |
| 2067 | +
|
| 2068 | + :return: Number of days |
| 2069 | + :rtype: int |
| 2070 | + """ |
| 2071 | + return self.period[1] - self.period[0] + 1 |
2034 | 2072 |
|
2035 | 2073 |
|
2036 | 2074 | @njit(cache=True) |
|
0 commit comments