Skip to content

Commit

Permalink
Merge pull request #221 from MaxGhenis/deeppovgap
Browse files Browse the repository at this point in the history
Add deep_poverty_gap function
  • Loading branch information
MaxGhenis authored Jun 28, 2021
2 parents 1df139f + a2a6843 commit c74ebe9
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 11 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
.ipynb_checkpoints

# Built Jupyter-Book documentation.
docs/_build
docs/_build

.vscode/settings.json
18 changes: 10 additions & 8 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions microdf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -132,6 +133,7 @@
"deep_poverty_rate",
"poverty_gap",
"squared_poverty_gap",
"deep_poverty_gap",
# style.py
"AXIS_COLOR",
"DPI",
Expand Down
16 changes: 16 additions & 0 deletions microdf/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 deep 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
Expand Down
24 changes: 24 additions & 0 deletions microdf/poverty.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
17 changes: 15 additions & 2 deletions microdf/tests/test_poverty.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
# Same in MicroDataFrame.
assert np.allclose(md.deep_poverty_gap("income", "threshold"), RES)

0 comments on commit c74ebe9

Please sign in to comment.