Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release(v0.3.3) #137

Merged
merged 7 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.3] - 2024-12-13

### Fixed

- `mode` in `zonal_stats`
- missing support for `zonal_stats` when dataset had no time dimension

### Changed

- xarray accessor classes are now privates to avoid having them in autocomplementation.

## [0.3.2] - 2024-12-10

### Added
Expand Down
4 changes: 2 additions & 2 deletions earthdaily/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from typing import Optional
from pathlib import Path
from . import earthdatastore, datasets
from .accessor import EarthDailyAccessorDataArray, EarthDailyAccessorDataset
from .accessor import __EarthDailyAccessorDataArray, __EarthDailyAccessorDataset

# import warnings
# to hide warnings from rioxarray or nano seconds conversion
# warnings.filterwarnings("ignore")

__version__ = "0.3.2"
__version__ = "0.3.3"


def EarthDataStore(
Expand Down
4 changes: 2 additions & 2 deletions earthdaily/accessor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def _xr_rio_clip(datacube, geom):


@xr.register_dataarray_accessor("ed")
class EarthDailyAccessorDataArray:
class __EarthDailyAccessorDataArray:
def __init__(self, xarray_obj):
self._obj = xarray_obj

Expand Down Expand Up @@ -206,7 +206,7 @@ def drop_unfrozen_coords(self, keep_spatial_ref=True):


@xr.register_dataset_accessor("ed")
class EarthDailyAccessorDataset(EarthDailyAccessorDataArray):
class __EarthDailyAccessorDataset(__EarthDailyAccessorDataArray):
def __init__(self, xarray_obj):
self._obj = xarray_obj

Expand Down
19 changes: 8 additions & 11 deletions earthdaily/earthdatastore/cube_utils/_zonal.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from . import custom_reducers
from .preprocessing import rasterize
from scipy.sparse import csr_matrix
from scipy.stats import mode


def _compute_M(data):
Expand All @@ -26,13 +27,6 @@ def _indices_sparse(data):
return [np.unravel_index(row.data, data.shape) for row in M]


def _np_mode(arr, **kwargs):
values, counts = np.unique(arr, return_counts=True)
isnan = np.isnan(values)
values, counts = values[~isnan], counts[~isnan]
return values[np.argmax(counts)]


def datacube_time_stats(datacube, operations):
datacube = datacube.groupby("time")
stats = []
Expand Down Expand Up @@ -76,8 +70,11 @@ def _zonal_stats_ufunc(dataset, positions, reducers):
field_stats = []
for reducer in reducers:
field_arr = dataset[(...,) + tuple(positions[idx])]
func = f"nan{reducer}" if hasattr(np, f"nan{reducer}") else reducer
field_arr = getattr(np, func)(field_arr, axis=-1)
if reducer == "mode":
field_arr = mode(field_arr, axis=-1, nan_policy="omit").mode
else:
func = f"nan{reducer}" if hasattr(np, f"nan{reducer}") else reducer
field_arr = getattr(np, func)(field_arr, axis=-1)
field_stats.append(field_arr)
field_stats = np.asarray(field_stats)
zs.append(field_stats)
Expand Down Expand Up @@ -187,8 +184,8 @@ def _loop_time_chunks(dataset, method, smart_load, time_chunks):
positions = [np.asarray(yx_pos[i + 1]) for i in np.arange(geoms.shape[0])]
positions = [position for position in positions if position.size > 0]
del yx_pos
time_chunks = _memory_time_chunks(dataset, memory)
if smart_load:
if "time" in dataset.dims and smart_load:
time_chunks = _memory_time_chunks(dataset, memory)
zs = xr.concat(
[
z
Expand Down
2 changes: 1 addition & 1 deletion requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies:
- numpy
- matplotlib
- joblib
- gdal=3.7.3
- gdal
- scipy
- psutil
- pystac-client
Expand Down
2 changes: 1 addition & 1 deletion requirements_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies:
- numpy
- pandas
- libtiff
- gdal=3.7.3
- gdal
- geopandas>=0.11
- dask>=2024.3
- shapely
Expand Down
Loading