Skip to content

groupby_bins groups not correctly applied with built-in methods #7601

Closed
@michaelaye

Description

@michaelaye

What happened?

Setup

I want to calculate image statistics per chunk in one dimension. Let's assume a very small image for demonstration purposes:

a = xr.DataArray(np.arange(12).reshape(6,2), dims=('x', 'y'))
a

image
Trying to chunk this into three subimages, I use these bins into the x dimension:

x_bins = (0, 2, 4, 6)

I look at the groups this creates by default:

for iv, g in a.groupby_bins('x', x_bins):
    print(iv)
    print(g)

image
I don't understand the use-case for this grouping, as it's missing the beginning and is having uneven sized last group (Obviously a follow-error from not including the first row).

To force the even chunking of the image I need to call it with these parameters:

groups = a.groupby_bins('x', x_bins, include_lowest=True, right=False)
for iv, g in groups:
    print(iv)
    print(g)

image

Issue

But now, calculating the mean value of each group, I get different results when doing it by hand using the groups or doing it using the groups inherent method mean():

image

Indeed, I verified, that these results are what one gets, using the first version of applying the bins:
image

The same is true when I use the elliptical operator to receive the mean over the remaining dimensions (note, the 2nd cell here is using the groups variable as defined in the cell before, so should really return the same values, but it doesn't:
image

Application

I believe that groupby_bins is the most appropriate tool to do this in xarray. I wished that one could enforce the dask-chunks in dask arrays to survive and return stats from them, but haven't found a way to do that.

What did you expect to happen?

That the inherent stats methods of the groups method respect the interval use constraints from the groupby_bins call.

I also have verified that the same problem exists with groups.std().

Minimal Complete Verifiable Example

import xarray as xr
import numpy as np

a = xr.DataArray(np.arange(12).reshape(6,2), dims=('x', 'y'))

x_bins = (0, 2, 4, 6)

default_groups = a.groupby_bins('x', x_bins)
my_groups = a.groupby_bins('x', x_bins, include_lowest=True, right=False)

print("Weird grouping using default call:")
for iv, g in default_groups:
    print("Interval:",iv)
    print(g.data)
    print()
    
print("Evenly chunked using `my_groups`:")    
for iv, g in my_groups:
    print("Interval:", iv)
    print(g.data)
    print()

print("Calculating mean on my own using loop over groups:")
for iv, g in my_groups:
    print(g.mean('x').data)
    
print("Calculting same using my_groups.mean()")
print("No dim given:")
print(my_groups.mean().data.T)
print("using mean('x'):")
print(my_groups.mean('x').data.T)

print("These results come from the default groups!:")
for iv, g in default_groups:
    print(g.mean('x').data)
    
print("STD has the same issue")

MVCE confirmation

  • Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
  • Complete example — the example is self-contained, including all data and the text of any traceback.
  • Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
  • New issue — a search of GitHub Issues suggests this is not a duplicate.

Relevant log output

No response

Anything else we need to know?

No response

Environment

INSTALLED VERSIONS

commit: None
python: 3.10.9 | packaged by conda-forge | (main, Feb 2 2023, 20:20:04) [GCC 11.3.0]
python-bits: 64
OS: Linux
OS-release: 6.0.12-76060006-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LOCALE: ('en_US', 'UTF-8')
libhdf5: 1.12.2
libnetcdf: 4.9.1

xarray: 2023.2.0
pandas: 1.5.3
numpy: 1.23.5
scipy: 1.10.1
netCDF4: 1.6.3
pydap: None
h5netcdf: None
h5py: 3.8.0
Nio: None
zarr: None
cftime: 1.6.2
nc_time_axis: None
PseudoNetCDF: None
rasterio: 1.3.6
cfgrib: None
iris: None
bottleneck: 1.3.7
dask: 2023.3.0
distributed: 2023.3.0
matplotlib: 3.7.1
cartopy: 0.21.1
seaborn: 0.12.2
numbagg: None
fsspec: 2023.3.0
cupy: None
pint: None
sparse: None
flox: 0.6.8
numpy_groupies: 0.9.20
setuptools: 67.5.1
pip: 23.0.1
conda: installed
pytest: 7.1.3
mypy: None
IPython: 8.7.0
sphinx: None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions