Repository: martinfleis/momepy
Pull request #146 (2020-02-23 11:56:13)

ENH: SegmentsLength allow sum and mean at the same run
This is a breaking change. If `mean=True`, resulting series is in `self.mean`, not `self.series` anymore. Sum is computed always.

codecov[bot]: # [Codecov](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=h1) Report
> Merging [#146](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=desc) into [master](https://codecov.io/gh/martinfleis/momepy/commit/d097322d4de76d362f1561daeb8dbdb6ac31c67d?src=pr&el=desc) will **decrease** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/martinfleis/momepy/pull/146/graphs/tree.svg?width=650&token=i04999UxkK&height=150&src=pr)](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #146      +/-   ##
==========================================
- Coverage   93.53%   93.52%   -0.01%     
==========================================
  Files           9        9              
  Lines        2473     2472       -1     
==========================================
- Hits         2313     2312       -1     
  Misses        160      160
```


| [Impacted Files](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [momepy/dimension.py](https://codecov.io/gh/martinfleis/momepy/pull/146/diff?src=pr&el=tree#diff-bW9tZXB5L2RpbWVuc2lvbi5weQ==) | `97.28% <100%> (+0.03%)` | :arrow_up: |
| [momepy/diversity.py](https://codecov.io/gh/martinfleis/momepy/pull/146/diff?src=pr&el=tree#diff-bW9tZXB5L2RpdmVyc2l0eS5weQ==) | `90.78% <0%> (-0.44%)` | :arrow_down: |
| [momepy/distribution.py](https://codecov.io/gh/martinfleis/momepy/pull/146/diff?src=pr&el=tree#diff-bW9tZXB5L2Rpc3RyaWJ1dGlvbi5weQ==) | `98.44% <0%> (-0.01%)` | :arrow_down: |
| [momepy/intensity.py](https://codecov.io/gh/martinfleis/momepy/pull/146/diff?src=pr&el=tree#diff-bW9tZXB5L2ludGVuc2l0eS5weQ==) | `98.07% <0%> (+0.01%)` | :arrow_up: |
| [momepy/shape.py](https://codecov.io/gh/martinfleis/momepy/pull/146/diff?src=pr&el=tree#diff-bW9tZXB5L3NoYXBlLnB5) | `95.98% <0%> (+0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=footer). Last update [d097322...20d03f2](https://codecov.io/gh/martinfleis/momepy/pull/146?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/momepy/dimension.py b/momepy/dimension.py
index 10f4f83..69965fb 100644
--- a/momepy/dimension.py
+++ b/momepy/dimension.py
@@ -916,11 +916,11 @@ class PerimeterWall:
 
 class SegmentsLength:
     """
-    Calculate the cummulative or mean length of segments.
+    Calculate the cummulative and/or mean length of segments.
 
     Length of segments within set topological distance from each of them.
-    Reached topological distance should be captured by spatial_weights. If mean=False
-    it will return total length, if mean=True it will return mean value.
+    Reached topological distance should be captured by spatial_weights. If mean=False it
+    will compute sum of length, if mean=True it will compute sum and mean.
 
     Parameters
     ----------
@@ -930,29 +930,31 @@ class SegmentsLength:
         spatial weights matrix - If None, Queen contiguity matrix will be calculated
         based on streets (note: spatial_weights shoud be based on index, not unique ID).
     mean : boolean, optional
-        If mean=False it will return total length, if mean=True it will return mean value
+        If mean=False it will compute sum of length, if mean=True it will compute
+        sum and mean
 
     Attributes
     ----------
     series : Series
-        Series containing resulting values
+        Series containing resulting total lengths
+    mean : Series
+        Series containing resulting total lengths
+    sum : Series
+        Series containing resulting total lengths
     gdf : GeoDataFrame
         original GeoDataFrame
     sw : libpysal.weights
         spatial weights matrix
-    mean : boolean
-        used mean boolean value
 
     Examples
     --------
-    >>> streets_df['length_neighbours'] = mm.SegmentsLength(streets_df, mean=True).series
+    >>> streets_df['length_neighbours'] = mm.SegmentsLength(streets_df, mean=True).mean
     Calculating spatial weights...
     Spatial weights ready...
     """
 
     def __init__(self, gdf, spatial_weights=None, mean=False):
         self.gdf = gdf
-        self.mean = mean
 
         if spatial_weights is None:
             print("Calculating spatial weights...")
@@ -962,7 +964,10 @@ class SegmentsLength:
             print("Spatial weights ready...")
         self.sw = spatial_weights
 
-        results_list = []
+        lenghts = gdf.geometry.length
+
+        sums = []
+        means = []
         for index, row in tqdm(gdf.iterrows(), total=gdf.shape[0]):
             neighbours = spatial_weights.neighbors[index].copy()
             if neighbours:
@@ -970,10 +975,11 @@ class SegmentsLength:
             else:
                 neighbours = [index]
 
-            dims = gdf.iloc[neighbours].geometry.length
+            dims = lenghts.iloc[neighbours]
             if mean:
-                results_list.append(np.mean(dims))
-            else:
-                results_list.append(sum(dims))
+                means.append(np.mean(dims))
+            sums.append(sum(dims))
 
-        self.series = pd.Series(results_list, index=gdf.index)
+        self.series = self.sum = pd.Series(sums, index=gdf.index)
+        if mean:
+            self.mean = pd.Series(means, index=gdf.index)


Test patch:
diff --git a/tests/test_dimension.py b/tests/test_dimension.py
index 6fd3f3f..6259fc0 100644
--- a/tests/test_dimension.py
+++ b/tests/test_dimension.py
@@ -229,7 +229,7 @@ class TestDimensions:
         assert wall[0] == 137.2106961418436
 
     def test_SegmentsLength(self):
-        absol = mm.SegmentsLength(self.df_streets).series
-        mean = mm.SegmentsLength(self.df_streets, mean=True).series
+        absol = mm.SegmentsLength(self.df_streets).sum
+        mean = mm.SegmentsLength(self.df_streets, mean=True).mean
         assert max(absol) == 1907.502238338006
         assert max(mean) == 249.5698434867373