From e3c001de8c75fe85674b768ba14e4aa529ed9b36 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 14 Jun 2021 10:16:16 -0700 Subject: [PATCH 1/7] Add deep_poverty_gap --- .vscode/settings.json | 3 +++ microdf/poverty.py | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b9cb60a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/home/mghenis/anaconda3/bin/python" +} \ No newline at end of file diff --git a/microdf/poverty.py b/microdf/poverty.py index 6bc90f4..957ec0b 100644 --- a/microdf/poverty.py +++ b/microdf/poverty.py @@ -111,3 +111,27 @@ def squared_poverty_gap( if w is None: return sq_gap.sum() return (sq_gap * df[w]).sum() + + +def deep_poverty_gap( + df: pd.DataFrame, income: str, threshold: str, w: str = None +) -> float: + """Calculate deep poverty gap, i.e., the total gap between income and + halved poverty thresholds for all people in deep poverty. + + :param df: DataFrame with income, threshold, and possibly weight columns + for each household (data should represent households, not persons). + :type df: pd.DataFrame + :param income: Column indicating income. + :type income: str + :param threshold: Column indicating threshold. + :type threshold: str + :param w: Column indicating weight, defaults to None (unweighted). + :type w: str, optional + :return: Deep poverty gap. + :rtype: float + """ + gap = np.maximum((df[threshold] / 2) - df[income], 0) + if w is None: + return gap.sum() + return (gap * df[w]).sum() From abb8a60159f7ca00eb4836da797b57a540c38984 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 14 Jun 2021 10:27:02 -0700 Subject: [PATCH 2/7] Add deep_poverty_gap test and to __init__.py --- microdf/__init__.py | 2 ++ microdf/tests/test_poverty.py | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/microdf/__init__.py b/microdf/__init__.py index 03d7165..3e9d327 100644 --- a/microdf/__init__.py +++ b/microdf/__init__.py @@ -44,6 +44,7 @@ deep_poverty_rate, poverty_gap, squared_poverty_gap, + deep_poverty_gap, ) from .style import AXIS_COLOR, DPI, GRID_COLOR, TITLE_COLOR, set_plot_style from .tax import mtr, tax_from_mtrs @@ -132,6 +133,7 @@ "deep_poverty_rate", "poverty_gap", "squared_poverty_gap", + "deep_poverty_gap", # style.py "AXIS_COLOR", "DPI", diff --git a/microdf/tests/test_poverty.py b/microdf/tests/test_poverty.py index f32ec20..1d87423 100644 --- a/microdf/tests/test_poverty.py +++ b/microdf/tests/test_poverty.py @@ -53,7 +53,20 @@ def test_squared_poverty_gap(): # Weighted RES = 1 * (25 ** 2) + 2 * (10 ** 2) + 3 * (5 ** 2) assert np.allclose( - mdf.squared_poverty_gap(df, "income", "threshold", "weight"), - RES, + mdf.squared_poverty_gap(df, "income", "threshold", "weight"), RES, ) assert np.allclose(md.squared_poverty_gap("income", "threshold"), RES) + + +def test_deep_poverty_gap(): + # Unweighted + assert np.allclose( + mdf.deep_poverty_gap(df, "income", "threshold"), 17.5 + 5 + 0 + 0 + ) + # Weighted + RES = 17.5 * 1 + 5 * 2 + 0 * 3 + 0 * 4 + assert np.allclose( + mdf.deep_poverty_gap(df, "income", "threshold", "weight"), RES + ) + # Not yet in MicroDataFrame. + # assert np.allclose(md.deep_poverty_gap("income", "threshold"), RES) From 7016a7dbbd13d38c8abc6d41fdb5bc17cbd7a5ea Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 27 Jun 2021 15:15:37 -0700 Subject: [PATCH 3/7] Add MicroDataFrame.deep_poverty_gap --- microdf/generic.py | 16 ++++++++++++++++ microdf/tests/test_poverty.py | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/microdf/generic.py b/microdf/generic.py index b0906cf..7f90327 100644 --- a/microdf/generic.py +++ b/microdf/generic.py @@ -727,6 +727,22 @@ def poverty_gap(self, income: str, threshold: str) -> float: gaps = (threshold - income)[threshold > income] return gaps.sum() + @get_args_as_micro_series() + def deep_poverty_gap(self, income: str, threshold: str) -> float: + """Calculate deep poverty gap, i.e., the total gap between income and + half of poverty thresholds for all people in poverty. + + :param income: Column indicating income. + :type income: str + :param threshold: Column indicating threshold. + :type threshold: str + :return: Deep poverty gap. + :rtype: float + """ + deep_threshold = threshold / 2 + gaps = (deep_threshold - income)[deep_threshold > income] + return gaps.sum() + @get_args_as_micro_series() def squared_poverty_gap(self, income: str, threshold: str) -> float: """Calculate squared poverty gap, i.e., the total squared gap between diff --git a/microdf/tests/test_poverty.py b/microdf/tests/test_poverty.py index 1d87423..68df0c9 100644 --- a/microdf/tests/test_poverty.py +++ b/microdf/tests/test_poverty.py @@ -68,5 +68,5 @@ def test_deep_poverty_gap(): assert np.allclose( mdf.deep_poverty_gap(df, "income", "threshold", "weight"), RES ) - # Not yet in MicroDataFrame. - # assert np.allclose(md.deep_poverty_gap("income", "threshold"), RES) + # Same in MicroDataFrame. + assert np.allclose(md.deep_poverty_gap("income", "threshold"), RES) From 4cd6007e6a84a93d0489ab2c81dee006657706e5 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 27 Jun 2021 15:16:38 -0700 Subject: [PATCH 4/7] Add .vscode/settings.json to .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 920958e..dbf043a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ .ipynb_checkpoints # Built Jupyter-Book documentation. -docs/_build \ No newline at end of file +docs/_build + +.vscode/settings.json From 3a6e103dc7093e5b24323336ade3c92467a13c8f Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 27 Jun 2021 15:18:24 -0700 Subject: [PATCH 5/7] Remove .vscode/settings.json --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index b9cb60a..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "python.pythonPath": "/home/mghenis/anaconda3/bin/python" -} \ No newline at end of file From e794769baef6f799fa75fd304f645ace5181f926 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 27 Jun 2021 15:44:25 -0700 Subject: [PATCH 6/7] Update toc to new format --- docs/_toc.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/_toc.yml b/docs/_toc.yml index 76d3734..d8c8318 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -1,10 +1,12 @@ -- file: home +format: jb-article +root: home +sections: - file: examples sections: - - file: agg - - file: charts - - file: custom_taxes - - file: demo - - file: gini - - file: income_measures - - file: weighting + - file: agg + - file: charts + - file: custom_taxes + - file: demo + - file: gini + - file: income_measures + - file: weighting From a2a6843584e1eeaad576a9a0cb4c74e208299902 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 27 Jun 2021 20:45:05 -0700 Subject: [PATCH 7/7] Docstring update --- microdf/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microdf/generic.py b/microdf/generic.py index 7f90327..a22e2b5 100644 --- a/microdf/generic.py +++ b/microdf/generic.py @@ -730,7 +730,7 @@ def poverty_gap(self, income: str, threshold: str) -> float: @get_args_as_micro_series() def deep_poverty_gap(self, income: str, threshold: str) -> float: """Calculate deep poverty gap, i.e., the total gap between income and - half of poverty thresholds for all people in poverty. + half of poverty thresholds for all people in deep poverty. :param income: Column indicating income. :type income: str