Repository: CartoDB/cartoframes
Pull request #1722 (2021-03-10 15:07:14)

Dataset describe not in scientific notation


Patch:
diff --git a/cartoframes/data/observatory/catalog/dataset.py b/cartoframes/data/observatory/catalog/dataset.py
index ecbf714b..908786be 100644
--- a/cartoframes/data/observatory/catalog/dataset.py
+++ b/cartoframes/data/observatory/catalog/dataset.py
@@ -293,11 +293,14 @@ class Dataset(CatalogEntity):
         """
         return geom_coverage(self.geography)
 
-    def describe(self):
+    def describe(self, autoformat=True):
         """Shows a summary of the actual stats of the variables (columns) of the dataset.
         Some of the stats provided per variable are: avg, max, min, sum, range,
         stdev, q1, q3, median and interquartile_range
 
+        Args:
+            autoformat (boolean): set automatic format for values. Default is True.
+
         Returns:
             pandas.DataFrame
 
@@ -317,6 +320,11 @@ class Dataset(CatalogEntity):
                 # interquartile_range
 
         """
+        FLOAT_FORMAT = 'display.float_format'
+
+        if autoformat:
+            pd.set_option(FLOAT_FORMAT, lambda x: '%.3f' % x)
+
         return dataset_describe(self.variables)
 
     @classmethod
diff --git a/cartoframes/data/observatory/catalog/variable.py b/cartoframes/data/observatory/catalog/variable.py
index 6ac9db55..f7018c4d 100644
--- a/cartoframes/data/observatory/catalog/variable.py
+++ b/cartoframes/data/observatory/catalog/variable.py
@@ -1,3 +1,5 @@
+import pandas as pd
+
 from .entity import CatalogEntity
 from .repository.dataset_repo import get_dataset_repo
 from .repository.variable_repo import get_variable_repo
@@ -101,11 +103,14 @@ class Variable(CatalogEntity):
         _, _, dataset, _ = self.id.split('.')
         return dataset
 
-    def describe(self):
+    def describe(self, autoformat=True):
         """Shows a summary of the actual stats of the variable (column) of the dataset.
         Some of the stats provided per variable are: avg, max, min, sum, range,
         stdev, q1, q3, median and interquartile_range
 
+        Args:
+            autoformat (boolean): set automatic format for values. Default is True.
+
         Example:
 
             .. code::
@@ -122,6 +127,11 @@ class Variable(CatalogEntity):
                 # interquartile_range
 
         """
+        FLOAT_FORMAT = 'display.float_format'
+
+        if autoformat:
+            pd.set_option(FLOAT_FORMAT, lambda x: '%.3f' % x)
+
         data = self.data['summary_json']
         return variable_describe(data)
 
diff --git a/cartoframes/io/carto.py b/cartoframes/io/carto.py
index 51e51092..dd31522a 100644
--- a/cartoframes/io/carto.py
+++ b/cartoframes/io/carto.py
@@ -55,7 +55,7 @@ def read_carto(source, credentials=None, limit=None, retry_times=3, schema=None,
 
     df = context_manager.copy_to(source, schema, limit, retry_times)
 
-    gdf = GeoDataFrame(df, crs='epsg:4326')
+    gdf = GeoDataFrame(df)
 
     if index_col:
         if index_col in gdf:
@@ -65,7 +65,7 @@ def read_carto(source, credentials=None, limit=None, retry_times=3, schema=None,
 
     if decode_geom and GEOM_COLUMN_NAME in gdf:
         # Decode geometry column
-        set_geometry(gdf, GEOM_COLUMN_NAME, inplace=True)
+        set_geometry(gdf, GEOM_COLUMN_NAME, inplace=True, crs='epsg:4326')
 
         if null_geom_value is not None:
             gdf[GEOM_COLUMN_NAME].fillna(null_geom_value, inplace=True)
diff --git a/cartoframes/viz/map.py b/cartoframes/viz/map.py
index eba469d7..d026d7bf 100644
--- a/cartoframes/viz/map.py
+++ b/cartoframes/viz/map.py
@@ -271,7 +271,7 @@ def _get_bounds(bounds, layers):
 def _init_layers(layers, parent_map):
     if layers is None:
         return []
-    if not isinstance(layers, collections.Iterable):
+    if not isinstance(layers, collections.abc.Iterable):
         layers.reset_ui(parent_map)
         return [layers]
     else:


Test patch:
diff --git a/tests/unit/data/observatory/catalog/examples.py b/tests/unit/data/observatory/catalog/examples.py
index 36737cae..7730cd3f 100644
--- a/tests/unit/data/observatory/catalog/examples.py
+++ b/tests/unit/data/observatory/catalog/examples.py
@@ -147,7 +147,7 @@ db_variable2 = {
     'dataset_id': 'dataset1',
     'agg_method': '',
     'variable_group_id': 'vargroup1',
-    'summary_json': [{'key': 'value'}]
+    'summary_json': {'key': 'value', 'stats': {'v': 1.23456789}, 'quantiles': {}}
 }
 test_variable1 = Variable(db_variable1)
 test_variable2 = Variable(db_variable2)
diff --git a/tests/unit/data/observatory/catalog/test_dataset.py b/tests/unit/data/observatory/catalog/test_dataset.py
index 9d3b519e..46d6f24e 100644
--- a/tests/unit/data/observatory/catalog/test_dataset.py
+++ b/tests/unit/data/observatory/catalog/test_dataset.py
@@ -3,7 +3,7 @@ import os
 import pytest
 import pandas as pd
 
-from unittest.mock import patch
+from unittest.mock import patch, ANY
 from pyrestcli.exceptions import ServerErrorException
 
 from cartoframes.auth import Credentials
@@ -199,6 +199,32 @@ class TestDataset(object):
         # Then
         assert isinstance(summary, pd.Series)
 
+    @patch.object(pd, 'set_option')
+    @patch.object(VariableRepository, 'get_all')
+    def test_summary_describe(self, mocked_repo, mocked_set):
+        # Given
+        dataset = Dataset(db_dataset2)
+
+        # When
+        summary = dataset.describe()
+
+        # Then
+        assert isinstance(summary, pd.DataFrame)
+        mocked_set.assert_called_once_with('display.float_format', ANY)
+
+    @patch.object(pd, 'set_option')
+    @patch.object(VariableRepository, 'get_all')
+    def test_summary_describe_custom_format(self, mocked_repo, mocked_set):
+        # Given
+        dataset = Dataset(db_dataset2)
+
+        # When
+        summary = dataset.describe(autoformat=False)
+
+        # Then
+        assert isinstance(summary, pd.DataFrame)
+        mocked_set.assert_not_called()
+
     @patch.object(DatasetRepository, 'get_all')
     def test_get_all_datasets(self, mocked_repo):
         # Given
diff --git a/tests/unit/data/observatory/catalog/test_variable.py b/tests/unit/data/observatory/catalog/test_variable.py
index a51ae7e1..15e5db28 100644
--- a/tests/unit/data/observatory/catalog/test_variable.py
+++ b/tests/unit/data/observatory/catalog/test_variable.py
@@ -1,6 +1,6 @@
 import pandas as pd
 
-from unittest.mock import patch
+from unittest.mock import patch, ANY
 
 from cartoframes.data.observatory.catalog.entity import CatalogList
 from cartoframes.data.observatory.catalog.variable import Variable
@@ -176,3 +176,27 @@ class TestVariable(object):
         assert isinstance(variable_df, pd.DataFrame)
         assert isinstance(sliced_variable, pd.Series)
         assert sliced_variable.equals(expected_variable_df)
+
+    @patch.object(pd, 'set_option')
+    @patch.object(VariableRepository, 'get_all')
+    def test_summary_describe(self, mocked_repo, mocked_set):
+        # Given
+        variable = test_variables[0]
+
+        # When
+        variable.describe()
+
+        # Then
+        mocked_set.assert_called_once_with('display.float_format', ANY)
+
+    @patch.object(pd, 'set_option')
+    @patch.object(VariableRepository, 'get_all')
+    def test_summary_describe_custom_format(self, mocked_repo, mocked_set):
+        # Given
+        variable = test_variables[0]
+
+        # When
+        variable.describe(autoformat=False)
+
+        # Then
+        mocked_set.assert_not_called()
diff --git a/tests/unit/viz/test_source.py b/tests/unit/viz/test_source.py
index 8aeec39c..96994d07 100644
--- a/tests/unit/viz/test_source.py
+++ b/tests/unit/viz/test_source.py
@@ -147,7 +147,7 @@ class TestSource(object):
         source = Source(gdf)
 
         assert source.datetime_column_names == ['date_column']
-        assert source.gdf.dtypes['date_column'] == np.object
+        assert source.gdf.dtypes['date_column'] == object
 
     @pytest.mark.parametrize('features', [
         [POINT],