-
Notifications
You must be signed in to change notification settings - Fork 17
Support heterogeneous datasets with scalar variables in from_dataset #169
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
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,7 +87,30 @@ If you omit `table_names`, each table is named by joining its dimension names | |
| with underscores, e.g. `era5.time_latitude_longitude` and | ||
| `era5.time_level_latitude_longitude`. | ||
|
|
||
| A runnable version of this example lives at | ||
| ## GOES satellite imagery (scalar variables) | ||
|
|
||
| Real-world stores often mix gridded data with scalar (0-dimensional) metadata. | ||
| GOES satellite imagery, for example, pairs `(y, x)` image bands with dozens of | ||
| scalar variables such as `goes_imager_projection`. `from_dataset` groups all the | ||
| scalars into a single one-row table named `scalar`: | ||
|
|
||
| ```python | ||
| import xarray as xr | ||
| from xarray_sql import XarrayContext | ||
|
|
||
| # A GOES-16 ABI cloud-and-moisture file: (y, x) bands + scalar metadata. | ||
| ds = xr.open_dataset('OR_ABI-L2-MCMIPM1-M6_G16_....nc').chunk({'y': 250, 'x': 250}) | ||
|
|
||
| ctx = XarrayContext() | ||
| ctx.from_dataset('goes', ds) | ||
|
|
||
| ctx.sql('SELECT COUNT(*) FROM goes.y_x') # the gridded bands | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add python comments to show that this prints? Same with the line below.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added # -> output comments on both queries (250000 and (1, 89)). |
||
| ctx.sql('SELECT * FROM goes.scalar') # one row of metadata | ||
| ``` | ||
|
|
||
| Override the default name like any other group with `table_names={(): 'metadata'}`. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, this is helpful. |
||
|
|
||
| A runnable version of the ERA5 example lives at | ||
| [`perf_tests/era5_temp_profile.py`](../perf_tests/era5_temp_profile.py). | ||
|
|
||
| [arco-era5]: https://github.com/google-research/arco-era5 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,10 +86,12 @@ def from_dataset( | |
| self.catalog().register_schema(name, schema) | ||
|
|
||
| for dims, var_names in groups.items(): | ||
| sub_name = table_names.get(dims, "_".join(dims)) | ||
| sub_ds = input_table[var_names] | ||
| schema.register_table(sub_name, read_xarray_table(sub_ds, chunks)) | ||
| self._maybe_register_cftime_udf(sub_ds) | ||
|
alxmrs marked this conversation as resolved.
|
||
| # Scalar variables group under empty dims, where "_".join(()) is | ||
| # the empty string; fall back to a valid default table name. | ||
| sub_name = table_names.get(dims, "_".join(dims) or "scalar") | ||
| self._from_dataset( | ||
| sub_name, input_table[var_names], chunks, schema=schema | ||
| ) | ||
|
|
||
| return self | ||
|
|
||
|
|
@@ -98,11 +100,17 @@ def _from_dataset( | |
| table_name: str, | ||
| input_table: xr.Dataset, | ||
| chunks: Chunks = None, | ||
| schema: Schema | None = None, | ||
| ): | ||
| """Register a uniform-dimension Dataset as a single SQL table.""" | ||
| """Register a Dataset as a single SQL table. | ||
|
|
||
| table = read_xarray_table(input_table, chunks) | ||
| self.register_table(table_name, table) | ||
| Registers a top-level table by default, or a table inside ``schema`` | ||
| (a SQL namespace) when one is given. | ||
| """ | ||
| register = ( | ||
| self.register_table if schema is None else schema.register_table | ||
| ) | ||
| register(table_name, read_xarray_table(input_table, chunks)) | ||
| self._maybe_register_cftime_udf(input_table) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, why was this deleted?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing, |
||
| return self | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not abbreviate this path. I think the code should be copy and pastable and work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, it now pulls a real GOES-16 file from NOAA's public bucket and runs end to end.