From 5e6f1b9130f2ac3baa070073379eebfc2d2936a8 Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Wed, 30 Oct 2024 22:34:55 -0300 Subject: [PATCH 01/10] feat: ee.Dictionary.toTable + tests --- geetools/ee_dictionary.py | 41 ++++++++++++++++++++ tests/test_Dictionary.py | 26 +++++++++++++ tests/test_Dictionary/test_to_table_any.yml | 12 ++++++ tests/test_Dictionary/test_to_table_dict.yml | 18 +++++++++ tests/test_Dictionary/test_to_table_list.yml | 18 +++++++++ 5 files changed, 115 insertions(+) create mode 100644 tests/test_Dictionary/test_to_table_any.yml create mode 100644 tests/test_Dictionary/test_to_table_dict.yml create mode 100644 tests/test_Dictionary/test_to_table_list.yml diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index 16dcba79..e8bacc96 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -1,6 +1,8 @@ """Extra methods for the ``ee.Dictionary`` class.""" from __future__ import annotations +from typing import Any + import ee from .accessors import register_class_accessor @@ -80,3 +82,42 @@ def getMany(self, list: list | ee.List) -> ee.List: d.geetools.getMany(["foo", "bar"]).getInfo() """ return ee.List(list).map(lambda key: self._obj.get(key)) + + def toTable(self, valueType: ee.List | ee.Dictionary | Any = Any) -> ee.FeatureCollection: + """Convert a ee.Dictionary to a ee.FeatureCollection with no geometries (table). + + The keys will always be stored in `system:index` column. + + Parameters: + valueType: this will define how to process the values. In case of + ee.List the values will be stored in columns named `value_`. + In case of a ee.Dictionary, column names will be created from the keys. + For any other type, it will return a table with one feature with + one column per key. + + Returns: + a ee.FeatureCollection in which the keys of the ee.Dictionary are + in the `system:index` and the values are in new columns. + """ + + def features_from_dict(key, value) -> ee.Feature: + key = ee.String(key) + feat = ee.Feature(None, {"system:index": key}) + return feat.set(ee.Dictionary(value)) + + def features_from_list(key, value) -> ee.Feature: + key = ee.String(key) + feat = ee.Feature(None, {"system:index": key}) + value = ee.List(value) + keys = ee.List.sequence(1, value.size()) + keys = keys.map(lambda k: ee.String("value_").cat(ee.Number(k).toInt())) + properties = ee.Dictionary.fromLists(keys, value) + return feat.set(properties) + + if valueType == ee.Dictionary: + features = self._obj.map(features_from_dict).values() + elif valueType == ee.List: + features = self._obj.map(features_from_list).values() + else: + return ee.FeatureCollection([ee.Feature(None, self._obj)]) + return ee.FeatureCollection(features) diff --git a/tests/test_Dictionary.py b/tests/test_Dictionary.py index 9e410cea..38c2598a 100644 --- a/tests/test_Dictionary.py +++ b/tests/test_Dictionary.py @@ -1,6 +1,8 @@ """Test the Dictionary class methods.""" import ee +import geetools # noqa + class TestFromPairs: """Test the fromPairs method.""" @@ -28,3 +30,27 @@ class TestGetMany: def test_getMany(self): d = ee.Dictionary({"foo": 1, "bar": 2}).geetools.getMany(["foo"]) assert d.getInfo() == [1] + + +class TestToTable: + """Test the `toTable` method.""" + + def test_to_table_any(self, data_regression): + ee_dict = ee.Dictionary({"ADM0_NAME": "Argentina", "ADM0_CODE": "12"}) + res = ee_dict.geetools.toTable() + data_regression.check(res.getInfo()) + + def test_to_table_list(self, data_regression): + ee_dict = ee.Dictionary({"Argentina": [12, 278.289196625], "Armenia": [13, 3.13783139285]}) + res = ee_dict.geetools.toTable(ee.List) + data_regression.check(res.getInfo()) + + def test_to_table_dict(self, data_regression): + ee_dict = ee.Dictionary( + { + "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, + "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, + } + ) + res = ee_dict.geetools.toTable(ee.Dictionary) + data_regression.check(res.getInfo()) diff --git a/tests/test_Dictionary/test_to_table_any.yml b/tests/test_Dictionary/test_to_table_any.yml new file mode 100644 index 00000000..d55c7e20 --- /dev/null +++ b/tests/test_Dictionary/test_to_table_any.yml @@ -0,0 +1,12 @@ +columns: + ADM0_CODE: String + ADM0_NAME: String + system:index: String +features: +- geometry: null + id: '0' + properties: + ADM0_CODE: '12' + ADM0_NAME: Argentina + type: Feature +type: FeatureCollection diff --git a/tests/test_Dictionary/test_to_table_dict.yml b/tests/test_Dictionary/test_to_table_dict.yml new file mode 100644 index 00000000..2caca78b --- /dev/null +++ b/tests/test_Dictionary/test_to_table_dict.yml @@ -0,0 +1,18 @@ +columns: + ADM0_CODE: Integer + Shape_Area: Float + system:index: String +features: +- geometry: null + id: Argentina + properties: + ADM0_CODE: 12 + Shape_Area: 278.289196625 + type: Feature +- geometry: null + id: Armenia + properties: + ADM0_CODE: 13 + Shape_Area: 3.13783139285 + type: Feature +type: FeatureCollection diff --git a/tests/test_Dictionary/test_to_table_list.yml b/tests/test_Dictionary/test_to_table_list.yml new file mode 100644 index 00000000..2f762b23 --- /dev/null +++ b/tests/test_Dictionary/test_to_table_list.yml @@ -0,0 +1,18 @@ +columns: + system:index: String + value_1: Integer + value_2: Float +features: +- geometry: null + id: Argentina + properties: + value_1: 12 + value_2: 278.289196625 + type: Feature +- geometry: null + id: Armenia + properties: + value_1: 13 + value_2: 3.13783139285 + type: Feature +type: FeatureCollection From 8eafa4a14c9bfc6da9a8c56d411e526aa0e255a2 Mon Sep 17 00:00:00 2001 From: Rambaud Pierrick <12rambau@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:19:09 +0100 Subject: [PATCH 02/10] Update geetools/ee_dictionary.py --- geetools/ee_dictionary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index e8bacc96..7e51f36b 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -84,7 +84,7 @@ def getMany(self, list: list | ee.List) -> ee.List: return ee.List(list).map(lambda key: self._obj.get(key)) def toTable(self, valueType: ee.List | ee.Dictionary | Any = Any) -> ee.FeatureCollection: - """Convert a ee.Dictionary to a ee.FeatureCollection with no geometries (table). + """Convert a :py:class:`ee.Dictionary` to a :py:class:`ee.FeatureCollection` with no geometries (table). The keys will always be stored in `system:index` column. From f4155dc6e6b473fbe9aa66829416fd601ee39a51 Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Fri, 10 Jan 2025 09:19:35 -0300 Subject: [PATCH 03/10] fix: index starts at 0 now. New approach for dictionaries where values are not dict or list. New building blocks. --- geetools/ee_dictionary.py | 25 +++++++++++--------- tests/test_Dictionary/test_to_table_any.yml | 13 ++++++---- tests/test_Dictionary/test_to_table_list.yml | 12 +++++----- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index 7e51f36b..db20112d 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -101,23 +101,26 @@ def toTable(self, valueType: ee.List | ee.Dictionary | Any = Any) -> ee.FeatureC """ def features_from_dict(key, value) -> ee.Feature: - key = ee.String(key) - feat = ee.Feature(None, {"system:index": key}) - return feat.set(ee.Dictionary(value)) + index = {"system:index": ee.String(key)} + props = ee.Dictionary(value).combine(index) + return ee.Feature(None, props) def features_from_list(key, value) -> ee.Feature: - key = ee.String(key) - feat = ee.Feature(None, {"system:index": key}) - value = ee.List(value) - keys = ee.List.sequence(1, value.size()) - keys = keys.map(lambda k: ee.String("value_").cat(ee.Number(k).toInt())) - properties = ee.Dictionary.fromLists(keys, value) - return feat.set(properties) + index = {"system:index": ee.String(key)} + values = ee.List(value) + columns = ee.List.sequence(0, values.size().subtract(1)) + columns = columns.map(lambda k: ee.String("value_").cat(ee.Number(k).toInt())) + props = ee.Dictionary.fromLists(columns, values).combine(index) + return ee.Feature(None, props) + + def features_from_any(key, value) -> ee.Feature: + props = {"system:index": ee.String(key), "value": value} + return ee.Feature(None, props) if valueType == ee.Dictionary: features = self._obj.map(features_from_dict).values() elif valueType == ee.List: features = self._obj.map(features_from_list).values() else: - return ee.FeatureCollection([ee.Feature(None, self._obj)]) + features = self._obj.map(features_from_any).values() return ee.FeatureCollection(features) diff --git a/tests/test_Dictionary/test_to_table_any.yml b/tests/test_Dictionary/test_to_table_any.yml index d55c7e20..550ea79f 100644 --- a/tests/test_Dictionary/test_to_table_any.yml +++ b/tests/test_Dictionary/test_to_table_any.yml @@ -1,12 +1,15 @@ columns: - ADM0_CODE: String - ADM0_NAME: String system:index: String + value: String features: - geometry: null - id: '0' + id: ADM0_CODE properties: - ADM0_CODE: '12' - ADM0_NAME: Argentina + value: '12' + type: Feature +- geometry: null + id: ADM0_NAME + properties: + value: Argentina type: Feature type: FeatureCollection diff --git a/tests/test_Dictionary/test_to_table_list.yml b/tests/test_Dictionary/test_to_table_list.yml index 2f762b23..3066264a 100644 --- a/tests/test_Dictionary/test_to_table_list.yml +++ b/tests/test_Dictionary/test_to_table_list.yml @@ -1,18 +1,18 @@ columns: system:index: String - value_1: Integer - value_2: Float + value_0: Integer + value_1: Float features: - geometry: null id: Argentina properties: - value_1: 12 - value_2: 278.289196625 + value_0: 12 + value_1: 278.289196625 type: Feature - geometry: null id: Armenia properties: - value_1: 13 - value_2: 3.13783139285 + value_0: 13 + value_1: 3.13783139285 type: Feature type: FeatureCollection From 9cbc641de027a39939f256b80a1d3513371d83e8 Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Mon, 13 Jan 2025 08:45:42 -0300 Subject: [PATCH 04/10] fix: improve long description docstring --- geetools/ee_dictionary.py | 129 +++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index db20112d..aae08dbd 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -86,7 +86,134 @@ def getMany(self, list: list | ee.List) -> ee.List: def toTable(self, valueType: ee.List | ee.Dictionary | Any = Any) -> ee.FeatureCollection: """Convert a :py:class:`ee.Dictionary` to a :py:class:`ee.FeatureCollection` with no geometries (table). - The keys will always be stored in `system:index` column. + There are 3 different type of values handled by this method: + + 1. Any (default): when values are a `ee.String` or `ee.Number`, the + keys will be saved in the column "system:index" and the values in the + column "value". + + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + d = ee.Dictionary({"foo": 1, "bar": 2}) + d.geetools.toTable().getInfo() + + >> { + 'type': FeatureCollection, + 'columns': { + 'system:index': String, + 'value': String + }, + features: [ + { + 'type': Feature, + 'geometry': null, + 'id': 'foo', + 'properties': { + 'value': 1, + }, + }, + { + 'type': Feature, + 'geometry': null, + 'id': 'bar', + 'properties': { + 'value': 2, + }, + } + ]} + + 2. ee.Dictionary: when values are a ee.Dictionary, the + keys will be saved in the column "system:index" and the values will be + treated as each Feature's properties. + + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + d = ee.Dictionary({ + "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, + "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, + }) + d.geetools.toTable().getInfo() + + >> { + 'type': FeatureCollection, + 'columns': { + 'system:index': String, + 'ADM0_CODE': Integer, + 'Shape_Area': Float + }, + features: [ + { + 'type': Feature, + 'geometry': null, + 'id': 'Argentina', + 'properties': { + 'ADM0_CODE': 12 + 'Shape_Area': 278.289196625 + }, + }, + { + 'type': Feature, + 'geometry': null, + 'id': 'Armenia', + 'properties': { + 'ADM0_CODE': 13 + 'Shape_Area': 3.13783139285 + }, + } + ]} + + 3. ee.List: when values are a ee.List of numbers or strings, the + keys will be saved in the column "system:index" and the values in + as many columns as items in the list. The column name pattern is + "value_{i}" where i is the position of the element in the list. + + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + d = ee.Dictionary({ + "Argentina": [12, 278.289196625], + "Armenia": [13, 3.13783139285], + }) + d.geetools.toTable().getInfo() + + >> { + 'type': FeatureCollection, + 'columns': { + 'system:index': String, + 'value_0': Integer, + 'value_1': Float + }, + features: [ + { + 'type': Feature, + 'geometry': null, + 'id': 'Argentina', + 'properties': { + 'value_0': 12 + 'value_1': 278.289196625 + }, + }, + { + 'type': Feature, + 'geometry': null, + 'id': 'Armenia', + 'properties': { + 'value_0': 13 + 'value_1': 3.13783139285 + }, + } + ]} Parameters: valueType: this will define how to process the values. In case of From d1525a1261f7b04c65f8dd762c9ae81072df5a23 Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Mon, 13 Jan 2025 11:51:27 -0300 Subject: [PATCH 05/10] fix: adapt to PR comments --- geetools/ee_dictionary.py | 222 ++++++++++++++------------------------ tests/test_Dictionary.py | 4 +- 2 files changed, 85 insertions(+), 141 deletions(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index aae08dbd..e0f27353 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -1,7 +1,7 @@ """Extra methods for the ``ee.Dictionary`` class.""" from __future__ import annotations -from typing import Any +from typing import Literal import ee @@ -83,144 +83,88 @@ def getMany(self, list: list | ee.List) -> ee.List: """ return ee.List(list).map(lambda key: self._obj.get(key)) - def toTable(self, valueType: ee.List | ee.Dictionary | Any = Any) -> ee.FeatureCollection: + def toTable( + self, valueType: Literal["dict", "list", "value"] = "value" + ) -> ee.FeatureCollection: """Convert a :py:class:`ee.Dictionary` to a :py:class:`ee.FeatureCollection` with no geometries (table). There are 3 different type of values handled by this method: - 1. Any (default): when values are a `ee.String` or `ee.Number`, the - keys will be saved in the column "system:index" and the values in the - column "value". - - .. code-block:: python - - import ee, geetools - - ee.Initialize() - - d = ee.Dictionary({"foo": 1, "bar": 2}) - d.geetools.toTable().getInfo() - - >> { - 'type': FeatureCollection, - 'columns': { - 'system:index': String, - 'value': String - }, - features: [ - { - 'type': Feature, - 'geometry': null, - 'id': 'foo', - 'properties': { - 'value': 1, - }, - }, - { - 'type': Feature, - 'geometry': null, - 'id': 'bar', - 'properties': { - 'value': 2, - }, - } - ]} - - 2. ee.Dictionary: when values are a ee.Dictionary, the - keys will be saved in the column "system:index" and the values will be - treated as each Feature's properties. - - .. code-block:: python - - import ee, geetools - - ee.Initialize() - - d = ee.Dictionary({ - "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, - "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, - }) - d.geetools.toTable().getInfo() - - >> { - 'type': FeatureCollection, - 'columns': { - 'system:index': String, - 'ADM0_CODE': Integer, - 'Shape_Area': Float - }, - features: [ - { - 'type': Feature, - 'geometry': null, - 'id': 'Argentina', - 'properties': { - 'ADM0_CODE': 12 - 'Shape_Area': 278.289196625 - }, - }, - { - 'type': Feature, - 'geometry': null, - 'id': 'Armenia', - 'properties': { - 'ADM0_CODE': 13 - 'Shape_Area': 3.13783139285 - }, - } - ]} - - 3. ee.List: when values are a ee.List of numbers or strings, the - keys will be saved in the column "system:index" and the values in - as many columns as items in the list. The column name pattern is - "value_{i}" where i is the position of the element in the list. - - .. code-block:: python - - import ee, geetools - - ee.Initialize() - - d = ee.Dictionary({ - "Argentina": [12, 278.289196625], - "Armenia": [13, 3.13783139285], - }) - d.geetools.toTable().getInfo() - - >> { - 'type': FeatureCollection, - 'columns': { - 'system:index': String, - 'value_0': Integer, - 'value_1': Float - }, - features: [ - { - 'type': Feature, - 'geometry': null, - 'id': 'Argentina', - 'properties': { - 'value_0': 12 - 'value_1': 278.289196625 - }, - }, - { - 'type': Feature, - 'geometry': null, - 'id': 'Armenia', - 'properties': { - 'value_0': 13 - 'value_1': 3.13783139285 - }, - } - ]} + 1. value (default): when values are a `ee.String` or `ee.Number`, the + keys will be saved in the column "system:index" and the values in the + column "value". + + 2. dict: when values are a ee.Dictionary, the keys will be saved in the + column "system:index" and the values will be treated as each + Feature's properties. + + 3. list: when values are a ee.List of numbers or strings, the keys will + be saved in the column "system:index" and the values in as many + columns as items in the list. The column name pattern is "value_{i}" + where i is the position of the element in the list. + + These are the only supported patterns. Other patterns should be converted + to one of these. For example, the values of a reduction using the + reducer `ee.Reducer.frequencyHistogram()` are of type `ee.Array` and + the array contains lists. + + Examples: + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + d = ee.Dictionary({"foo": 1, "bar": 2}) + d.geetools.toTable().getInfo() + + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + d = ee.Dictionary({ + "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, + "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, + }) + d.geetools.toTable('dict').getInfo() + + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + d = ee.Dictionary({ + "Argentina": [12, 278.289196625], + "Armenia": [13, 3.13783139285], + }) + d.geetools.toTable().getInfo() + + .. code-block:: python + + import ee, geetools + + ee.Initialize() + + # reduction + ran = ee.Image.random().multiply(10).reduceRegion( + reducer=ee.Reducer.fixedHistogram(0, 1.1, 11), + geometry=ee.Geometry.Point([0,0]).buffer(1000), + scale=100 + ) + # process to get desired format + res = ee.Array(ee.Dictionary(ran).get('random')) + reslist = res.toList() + keys = reslist.map(lambda i: ee.Number(ee.List(i).get(0)).multiply(100).toInt().format()) + values = reslist.map(lambda i: ee.Number(ee.List(i).get(1)).toInt()) + final = ee.Dictionary.fromLists(keys, values) + # fetch + final.geetools.toTable().getInfo() Parameters: - valueType: this will define how to process the values. In case of - ee.List the values will be stored in columns named `value_`. - In case of a ee.Dictionary, column names will be created from the keys. - For any other type, it will return a table with one feature with - one column per key. + valueType: this will define how to process the values. Returns: a ee.FeatureCollection in which the keys of the ee.Dictionary are @@ -244,10 +188,10 @@ def features_from_any(key, value) -> ee.Feature: props = {"system:index": ee.String(key), "value": value} return ee.Feature(None, props) - if valueType == ee.Dictionary: - features = self._obj.map(features_from_dict).values() - elif valueType == ee.List: - features = self._obj.map(features_from_list).values() - else: - features = self._obj.map(features_from_any).values() + make_features = { + "list": features_from_list, + "dict": features_from_dict, + "value": features_from_any, + } + features = self._obj.map(make_features[valueType]).values() return ee.FeatureCollection(features) diff --git a/tests/test_Dictionary.py b/tests/test_Dictionary.py index 38c2598a..4b65b501 100644 --- a/tests/test_Dictionary.py +++ b/tests/test_Dictionary.py @@ -42,7 +42,7 @@ def test_to_table_any(self, data_regression): def test_to_table_list(self, data_regression): ee_dict = ee.Dictionary({"Argentina": [12, 278.289196625], "Armenia": [13, 3.13783139285]}) - res = ee_dict.geetools.toTable(ee.List) + res = ee_dict.geetools.toTable("list") data_regression.check(res.getInfo()) def test_to_table_dict(self, data_regression): @@ -52,5 +52,5 @@ def test_to_table_dict(self, data_regression): "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, } ) - res = ee_dict.geetools.toTable(ee.Dictionary) + res = ee_dict.geetools.toTable("dict") data_regression.check(res.getInfo()) From 8dae997991905a685f1f40ab05648bdf6a15b3ff Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Mon, 13 Jan 2025 20:25:07 -0300 Subject: [PATCH 06/10] fix: adapt to PR comments --- geetools/ee_dictionary.py | 40 ++++++++++++++++++++------------------- tests/test_Dictionary.py | 2 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index e0f27353..2afb25fa 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -90,23 +90,30 @@ def toTable( There are 3 different type of values handled by this method: - 1. value (default): when values are a `ee.String` or `ee.Number`, the - keys will be saved in the column "system:index" and the values in the - column "value". + 1. value (default): when values are a :py:class:`ee.String` or + :py:class:`ee.Number`, the keys will be saved in the column + ``system:index`` and the values in the column "value". - 2. dict: when values are a ee.Dictionary, the keys will be saved in the - column "system:index" and the values will be treated as each - Feature's properties. + 2. dict: when values are a :py:class:`ee.Dictionary`, the keys will be + saved in the column ``system:index`` and the values will be treated + as each Feature's properties. - 3. list: when values are a ee.List of numbers or strings, the keys will - be saved in the column "system:index" and the values in as many - columns as items in the list. The column name pattern is "value_{i}" - where i is the position of the element in the list. + 3. list: when values are a :py:class:ee.List of numbers or strings, + the keys will be saved in the column ``system:index`` and the values + in as many columns as items in the list. The column name pattern is + "value_{i}" where i is the position of the element in the list. These are the only supported patterns. Other patterns should be converted to one of these. For example, the values of a reduction using the - reducer `ee.Reducer.frequencyHistogram()` are of type `ee.Array` and - the array contains lists. + reducer :py:meth:`ee.Reducer.frequencyHistogram` are of type + :py:class:`ee.Array` and the array contains lists. + + Parameters: + valueType: this will define how to process the values. + + Returns: + a collection in which the keys of the :py:class:`ee.Dictionary` are + in the ``system:index`` and the values are in new columns. Examples: .. code-block:: python @@ -154,21 +161,16 @@ def toTable( geometry=ee.Geometry.Point([0,0]).buffer(1000), scale=100 ) + # process to get desired format res = ee.Array(ee.Dictionary(ran).get('random')) reslist = res.toList() keys = reslist.map(lambda i: ee.Number(ee.List(i).get(0)).multiply(100).toInt().format()) values = reslist.map(lambda i: ee.Number(ee.List(i).get(1)).toInt()) final = ee.Dictionary.fromLists(keys, values) + # fetch final.geetools.toTable().getInfo() - - Parameters: - valueType: this will define how to process the values. - - Returns: - a ee.FeatureCollection in which the keys of the ee.Dictionary are - in the `system:index` and the values are in new columns. """ def features_from_dict(key, value) -> ee.Feature: diff --git a/tests/test_Dictionary.py b/tests/test_Dictionary.py index 4b65b501..0d410eb3 100644 --- a/tests/test_Dictionary.py +++ b/tests/test_Dictionary.py @@ -36,7 +36,7 @@ class TestToTable: """Test the `toTable` method.""" def test_to_table_any(self, data_regression): - ee_dict = ee.Dictionary({"ADM0_NAME": "Argentina", "ADM0_CODE": "12"}) + ee_dict = ee.Dictionary({"foo": 1, "bar": 2}) res = ee_dict.geetools.toTable() data_regression.check(res.getInfo()) From 205b5ff869ee85f8f3f512e4f31c5a77852d9c10 Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Mon, 13 Jan 2025 20:25:30 -0300 Subject: [PATCH 07/10] fix: adapt to PR comments --- tests/test_Dictionary/test_to_table_any.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_Dictionary/test_to_table_any.yml b/tests/test_Dictionary/test_to_table_any.yml index 550ea79f..60027e13 100644 --- a/tests/test_Dictionary/test_to_table_any.yml +++ b/tests/test_Dictionary/test_to_table_any.yml @@ -1,15 +1,15 @@ columns: system:index: String - value: String + value: Integer features: - geometry: null - id: ADM0_CODE + id: bar properties: - value: '12' + value: 2 type: Feature - geometry: null - id: ADM0_NAME + id: foo properties: - value: Argentina + value: 1 type: Feature type: FeatureCollection From d99b35094c682420d24de427a61cb684bac6bb6e Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Mon, 13 Jan 2025 20:33:44 -0300 Subject: [PATCH 08/10] fix: adapt to sphinx --- geetools/ee_dictionary.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index 2afb25fa..4124d501 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -5,6 +5,8 @@ import ee +import geetools # noqa: F401 + from .accessors import register_class_accessor @@ -116,20 +118,22 @@ def toTable( in the ``system:index`` and the values are in new columns. Examples: - .. code-block:: python + .. jupyter-execute:: import ee, geetools + from geetools.utils import initialize_documentation - ee.Initialize() + initialize_documentation() d = ee.Dictionary({"foo": 1, "bar": 2}) d.geetools.toTable().getInfo() - .. code-block:: python + .. jupyter-execute:: import ee, geetools + from geetools.utils import initialize_documentation - ee.Initialize() + initialize_documentation() d = ee.Dictionary({ "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, @@ -137,11 +141,12 @@ def toTable( }) d.geetools.toTable('dict').getInfo() - .. code-block:: python + .. jupyter-execute:: import ee, geetools + from geetools.utils import initialize_documentation - ee.Initialize() + initialize_documentation() d = ee.Dictionary({ "Argentina": [12, 278.289196625], @@ -149,11 +154,12 @@ def toTable( }) d.geetools.toTable().getInfo() - .. code-block:: python + .. jupyter-execute:: import ee, geetools + from geetools.utils import initialize_documentation - ee.Initialize() + initialize_documentation() # reduction ran = ee.Image.random().multiply(10).reduceRegion( From 4c20d85369181ea8486ece5530d59d195cb5e8fa Mon Sep 17 00:00:00 2001 From: "Rodrigo E. Principe" Date: Mon, 13 Jan 2025 20:35:29 -0300 Subject: [PATCH 09/10] fix: I confused the file --- geetools/ee_dictionary.py | 2 -- tests/test_Dictionary.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index 4124d501..6f7c3349 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -5,8 +5,6 @@ import ee -import geetools # noqa: F401 - from .accessors import register_class_accessor diff --git a/tests/test_Dictionary.py b/tests/test_Dictionary.py index 0d410eb3..c2513676 100644 --- a/tests/test_Dictionary.py +++ b/tests/test_Dictionary.py @@ -1,7 +1,7 @@ """Test the Dictionary class methods.""" import ee -import geetools # noqa +import geetools # noqa: F401 class TestFromPairs: From 3b8bcae42c8cfc16d8077a91783f57a1e469e9a4 Mon Sep 17 00:00:00 2001 From: Rambaud Pierrick <12rambau@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:13:29 +0100 Subject: [PATCH 10/10] Update geetools/ee_dictionary.py --- geetools/ee_dictionary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geetools/ee_dictionary.py b/geetools/ee_dictionary.py index 6f7c3349..7cc7ac9b 100644 --- a/geetools/ee_dictionary.py +++ b/geetools/ee_dictionary.py @@ -98,7 +98,7 @@ def toTable( saved in the column ``system:index`` and the values will be treated as each Feature's properties. - 3. list: when values are a :py:class:ee.List of numbers or strings, + 3. list: when values are a :py:class:`ee.List` of numbers or strings, the keys will be saved in the column ``system:index`` and the values in as many columns as items in the list. The column name pattern is "value_{i}" where i is the position of the element in the list.