Repository: ydataai/ydata-profiling

Issue:
Counting negative values
**Missing functionality**
When asked to provide data overview, the number of negative value (and percentage) can be really helpful to assess data quality. I would like to add the number and the percentage of negative values to the summary.

**Proposed feature**
Look like it could be an easy implementation. Something like 
summary['n_neg'] = series.lt(0).sum()
summary['p_neg'] = series.lt(0).mean()

in describe_numeric_1d

**Alternatives considered**
None

**Additional context**
Would be happy to open my first ever  PR



Discussion:

Resolving patch:
diff --git a/src/pandas_profiling/model/summary_algorithms.py b/src/pandas_profiling/model/summary_algorithms.py
--- a/src/pandas_profiling/model/summary_algorithms.py
+++ b/src/pandas_profiling/model/summary_algorithms.py
@@ -181,6 +181,9 @@ def describe_numeric_1d(series: pd.Series, summary: dict) -> Tuple[pd.Series, di
     value_counts = summary["value_counts_without_nan"]
 
     summary["n_zeros"] = 0
+    negative_index = value_counts.index < 0
+    summary["n_negative"] = value_counts.loc[negative_index].sum()
+    summary["p_negative"] = summary["n_negative"] / summary["n"]
 
     infinity_values = [np.inf, -np.inf]
     infinity_index = value_counts.index.isin(infinity_values)
diff --git a/src/pandas_profiling/report/structure/variables/render_real.py b/src/pandas_profiling/report/structure/variables/render_real.py
--- a/src/pandas_profiling/report/structure/variables/render_real.py
+++ b/src/pandas_profiling/report/structure/variables/render_real.py
@@ -67,17 +67,17 @@ def render_real(summary):
                 "fmt": "fmt_percent",
                 "alert": "p_infinite" in summary["warn_fields"],
             },
-        ]
-    )
-
-    table2 = Table(
-        [
             {
                 "name": "Mean",
                 "value": summary["mean"],
                 "fmt": "fmt_numeric",
                 "alert": False,
             },
+        ]
+    )
+
+    table2 = Table(
+        [
             {
                 "name": "Minimum",
                 "value": summary["min"],
@@ -102,6 +102,18 @@ def render_real(summary):
                 "fmt": "fmt_percent",
                 "alert": "p_zeros" in summary["warn_fields"],
             },
+            {
+                "name": "Negative",
+                "value": summary["n_negative"],
+                "fmt": "fmt",
+                "alert": False,
+            },
+            {
+                "name": "Negative (%)",
+                "value": summary["p_negative"],
+                "fmt": "fmt_percent",
+                "alert": False,
+            },
             {
                 "name": "Memory size",
                 "value": summary["memory_size"],


Test patch:
diff --git a/tests/unit/test_describe.py b/tests/unit/test_describe.py
--- a/tests/unit/test_describe.py
+++ b/tests/unit/test_describe.py
@@ -223,6 +223,8 @@ def expected_results():
             "min": -10.0,
             "n_missing": 1,
             "p_missing": 0.11111111111111116,
+            "n_negative": 2,
+            "p_negative": 0.22222222222222222,
             "p_distinct": 6 / 8,
             "n": 9,
             "n_zeros": 2,
@@ -253,6 +255,8 @@ def expected_results():
             "min": -3.1415926535000001,
             "n_missing": 1,
             "p_missing": 0.11111111111111116,
+            "n_negative": 1,
+            "p_negative": 0.11111111111111116,
             "p_distinct": 1,
             "n_zeros": 0,
             "p_zeros": 0.0,
@@ -307,6 +311,8 @@ def expected_results():
             "min": 1.0,
             "n_missing": 0,
             "p_missing": 0.0,
+            "n_negative": 0,
+            "p_negative": 0.0,
             "n_infinite": 0,
             "n_distinct": 1,
             "p_distinct": 0.1111111111111111,