Fallback method for encoding dates using cftime. This method is more flexible than xarray's parsing using datetime64[ns] arrays but also slower because it loops over each element.
(dates, units: str, calendar: str)
| 956 | |
| 957 | |
| 958 | def _encode_datetime_with_cftime(dates, units: str, calendar: str) -> np.ndarray: |
| 959 | """Fallback method for encoding dates using cftime. |
| 960 | |
| 961 | This method is more flexible than xarray's parsing using datetime64[ns] |
| 962 | arrays but also slower because it loops over each element. |
| 963 | """ |
| 964 | if TYPE_CHECKING: |
| 965 | import cftime |
| 966 | else: |
| 967 | cftime = attempt_import("cftime") |
| 968 | |
| 969 | dates = np.asarray(dates) |
| 970 | original_shape = dates.shape |
| 971 | |
| 972 | if np.issubdtype(dates.dtype, np.datetime64): |
| 973 | # numpy's broken datetime conversion only works for us precision |
| 974 | dates = dates.astype("M8[us]").astype(datetime) |
| 975 | |
| 976 | dates = np.atleast_1d(dates) |
| 977 | |
| 978 | # Find all the None position |
| 979 | none_position = dates == None # noqa: E711 |
| 980 | filtered_dates = dates[~none_position] |
| 981 | |
| 982 | # Since netCDF files do not support storing float128 values, we ensure |
| 983 | # that float64 values are used by setting longdouble=False in num2date. |
| 984 | # This try except logic can be removed when xarray's minimum version of |
| 985 | # cftime is at least 1.6.2. |
| 986 | try: |
| 987 | encoded_nums = cftime.date2num( |
| 988 | filtered_dates, units, calendar, longdouble=False |
| 989 | ) |
| 990 | except TypeError: |
| 991 | encoded_nums = cftime.date2num(filtered_dates, units, calendar) |
| 992 | |
| 993 | if filtered_dates.size == none_position.size: |
| 994 | return encoded_nums.reshape(original_shape) |
| 995 | |
| 996 | # Create a full matrix of NaN |
| 997 | # And fill the num dates in the not NaN or None position |
| 998 | result = np.full(dates.shape, np.nan) |
| 999 | result[np.nonzero(~none_position)] = encoded_nums |
| 1000 | return result.reshape(original_shape) |
| 1001 | |
| 1002 | |
| 1003 | def cast_to_int_if_safe(num) -> np.ndarray: |
searching dependent graphs…