GRIB: ordering fields

We read an example GRIB file and load into a fieldlist. Then select a smaller subset for the examples.

[1]:
import earthkit.data as ekd

ds_in = ekd.from_source("sample", "tuv_pl.grib").to_fieldlist()
ds = ds_in.sel({"vertical.level": slice(500, 850), "parameter.variable": ["u", "v"]})
ds.ls()
[1]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
1 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
2 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
3 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
4 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
5 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll

Using order_by

order_by() returns a sorted fieldlist.

[2]:
ds.order_by("parameter.variable").ls()
[2]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
1 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
2 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
3 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
4 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
5 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll

The sorting keys can be specified as a list:

[3]:
ds.order_by(["parameter.variable", "vertical.level"]).ls()
[3]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
1 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
2 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
3 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
4 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
5 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll

We can prescribe the actual order within a key. It only works when all the possible values are specified:

[4]:
ds.order_by({"vertical.level": [500, 850, 700]}).ls()
[4]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
1 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
2 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
3 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
4 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
5 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll

Ordering direction

The default ordering direction is “ascending”.

[5]:
ds.order_by({"parameter.variable": "descending"}).ls()
[5]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
1 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
2 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
3 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
4 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
5 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
[6]:
ds.order_by({"parameter.variable": "descending", "vertical.level": "ascending"}).ls()
[6]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
1 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
2 v 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
3 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
4 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
5 u 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll

Custom ordering

[7]:
class _CustomOrder:
    def __call__(self, x, y):
        """
        Custom oridering.

        - 0: if x == y
        - 1: if x > y
        - -1: if x < y
        """
        if x == y:
            return 0

        # ascending below 500
        if x < 500 and y < 500:
            if x > y:
                return 1
            if x < y:
                return -1
        # descending above 500
        if x > 500 and y > 500:
            if x > y:
                return -1
            if x < y:
                return 1
        # otherwise
        else:
            if x > y:
                return 1
            if x < y:
                return -1


ds_in.sel({"parameter.variable": "t"}).order_by({"vertical.level": _CustomOrder()}).ls()
[7]:
parameter.variable time.valid_datetime time.base_datetime time.step vertical.level vertical.level_type ensemble.member geography.grid_type
0 t 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 300 pressure 0 regular_ll
1 t 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 400 pressure 0 regular_ll
2 t 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 500 pressure 0 regular_ll
3 t 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 1000 pressure 0 regular_ll
4 t 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 850 pressure 0 regular_ll
5 t 2018-08-01 12:00:00 2018-08-01 12:00:00 0 days 700 pressure 0 regular_ll
[ ]: