microdf-python 0.4.4__py3-none-any.whl → 0.4.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
microdf/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from .agg import agg, combine_base_reform, pctchg_base_reform
2
- from .chart_utils import dollar_format, currency_format
2
+ from .chart_utils import currency_format, dollar_format
3
3
  from .charts import quantile_pct_chg_plot
4
4
  from .concat import concat
5
5
  from .constants import (
@@ -25,6 +25,7 @@ from .custom_taxes import (
25
25
  add_ftt,
26
26
  add_vat,
27
27
  )
28
+ from .generic import MicroDataFrame, MicroSeries
28
29
  from .income_measures import cash_income, market_income, tpc_eci
29
30
  from .inequality import (
30
31
  bottom_50_pct_share,
@@ -32,19 +33,19 @@ from .inequality import (
32
33
  gini,
33
34
  t10_b50,
34
35
  top_0_1_pct_share,
35
- top_10_pct_share,
36
36
  top_1_pct_share,
37
+ top_10_pct_share,
37
38
  top_50_pct_share,
38
39
  top_x_pct_share,
39
40
  )
40
41
  from .io import read_stata_zip
41
42
  from .poverty import (
42
- fpl,
43
- poverty_rate,
43
+ deep_poverty_gap,
44
44
  deep_poverty_rate,
45
+ fpl,
45
46
  poverty_gap,
47
+ poverty_rate,
46
48
  squared_poverty_gap,
47
- deep_poverty_gap,
48
49
  )
49
50
  from .style import AXIS_COLOR, DPI, GRID_COLOR, TITLE_COLOR, set_plot_style
50
51
  from .tax import mtr, tax_from_mtrs
@@ -72,7 +73,6 @@ from .weighted import (
72
73
  weighted_quantile,
73
74
  weighted_sum,
74
75
  )
75
- from .generic import MicroDataFrame, MicroSeries
76
76
 
77
77
  name = "microdf"
78
78
  __version__ = "0.1.0"
microdf/_optional.py CHANGED
@@ -2,7 +2,7 @@ import distutils.version
2
2
  import importlib
3
3
  import types
4
4
  import warnings
5
-
5
+ from typing import Optional, Union
6
6
 
7
7
  # Adapted from:
8
8
  # https://github.com/pandas-dev/pandas/blob/master/pandas/compat/_optional.py
@@ -31,14 +31,13 @@ def _get_version(module: types.ModuleType) -> str:
31
31
 
32
32
  def import_optional_dependency(
33
33
  name: str,
34
- extra: str = "",
35
- raise_on_missing: bool = True,
36
- on_version: str = "raise",
37
- ):
38
- """Import an optional dependency.
39
- By default, if a dependency is missing an ImportError with a nice
40
- message will be raised. If a dependency is present, but too old,
41
- we raise.
34
+ extra: Optional[str] = "",
35
+ raise_on_missing: Optional[bool] = True,
36
+ on_version: Optional[str] = "raise",
37
+ ) -> Union[types.ModuleType, None]:
38
+ """Import an optional dependency. By default, if a dependency is missing an
39
+ ImportError with a nice message will be raised. If a dependency is present,
40
+ but too old, we raise.
42
41
 
43
42
  :param name: The module name. This should be top-level only, so that the
44
43
  version may be checked.
microdf/agg.py CHANGED
@@ -1,15 +1,16 @@
1
- import pandas as pd
2
1
  from typing import Optional
3
2
 
3
+ import pandas as pd
4
+
4
5
  import microdf as mdf
5
6
 
6
7
 
7
8
  def combine_base_reform(
8
9
  base: pd.DataFrame,
9
10
  reform: pd.DataFrame,
10
- base_cols: Optional[list],
11
- cols: Optional[list],
12
- reform_cols: Optional[list],
11
+ base_cols: Optional[list] = None,
12
+ cols: Optional[list] = None,
13
+ reform_cols: Optional[list] = None,
13
14
  ) -> pd.DataFrame:
14
15
  """Combine base and reform with certain columns.
15
16
 
@@ -25,7 +26,6 @@ def combine_base_reform(
25
26
  :type reform_cols: list, optional
26
27
  :returns: DataFrame with columns for base ("_base") and reform ("_reform").
27
28
  :rtype: pd.DataFrame
28
-
29
29
  """
30
30
  all_base_cols = mdf.listify([base_cols] + [cols])
31
31
  all_reform_cols = mdf.listify([reform_cols] + [cols])
@@ -35,17 +35,15 @@ def combine_base_reform(
35
35
 
36
36
 
37
37
  def pctchg_base_reform(combined: pd.DataFrame, metric: str) -> pd.Series:
38
- """Calculates the percentage change in a metric for a combined
39
- dataset.
38
+ """Calculates the percentage change in a metric for a combined dataset.
40
39
 
41
40
  :param combined: Combined DataFrame with _base and _reform columns.
42
41
  :type combined: pd.DataFrame
43
- :param metric: String of the column to calculate the difference.
44
- Must exist as metric_m_base and metric_m_reform in combined.
42
+ :param metric: String of the column to calculate the difference. Must exist
43
+ as metric_m_base and metric_m_reform in combined.
45
44
  :type metric: str
46
45
  :returns: Series with percentage change.
47
46
  :rtype: pd.Series
48
-
49
47
  """
50
48
  return combined[metric + "_m_reform"] / combined[metric + "_m_base"] - 1
51
49
 
@@ -55,8 +53,8 @@ def agg(
55
53
  reform: pd.DataFrame,
56
54
  groupby: str,
57
55
  metrics: list,
58
- base_metrics: Optional[list],
59
- reform_metrics: Optional[list],
56
+ base_metrics: Optional[list] = None,
57
+ reform_metrics: Optional[list] = None,
60
58
  ) -> pd.DataFrame:
61
59
  """Aggregates differences between base and reform.
62
60
 
@@ -67,8 +65,8 @@ def agg(
67
65
  :param groupby: Variable in base to group on.
68
66
  :type groupby: str
69
67
  :param metrics: List of variables to agg and calculate the % change of.
70
- These should have associated weighted columns ending in _m in base
71
- and reform.
68
+ These should have associated weighted columns ending in _m in base and
69
+ reform.
72
70
  :type metrics: list
73
71
  :param base_metrics: List of variables from base to sum.
74
72
  :type base_metrics: Optional[list]
@@ -76,7 +74,6 @@ def agg(
76
74
  :type reform_metrics: Optional[list]
77
75
  :returns: DataFrame with groupby and metrics, and _pctchg metrics.
78
76
  :rtype: pd.DataFrame
79
-
80
77
  """
81
78
  metrics = mdf.listify(metrics)
82
79
  metrics_m = [i + "_m" for i in metrics]
microdf/chart_utils.py CHANGED
@@ -1,28 +1,33 @@
1
- def dollar_format(suffix=""):
1
+ from typing import Optional
2
+
3
+ from matplotlib.ticker import FuncFormatter
4
+
5
+
6
+ def dollar_format(suffix: Optional[str] = "") -> "FuncFormatter":
2
7
  """Dollar formatter for matplotlib.
3
8
 
4
9
  :param suffix: Suffix to append, e.g. 'B'. Defaults to ''.
5
10
  :returns: FuncFormatter.
6
-
7
11
  """
8
12
  return currency_format(currency="USD", suffix=suffix)
9
13
 
10
14
 
11
- def currency_format(currency="USD", suffix=""):
15
+ def currency_format(
16
+ currency: Optional[str] = "USD", suffix: Optional[str] = ""
17
+ ) -> "FuncFormatter":
12
18
  """Currency formatter for matplotlib.
13
19
 
14
20
  :param currency: Name of the currency, e.g. 'USD', 'GBP'.
15
21
  :param suffix: Suffix to append, e.g. 'B'. Defaults to ''.
16
22
  :returns: FuncFormatter.
17
-
18
23
  """
19
24
  try:
20
25
  import matplotlib as mpl
21
26
  except ImportError:
22
27
  raise ImportError(
23
- "The function you've called requires extra dependencies. " +
24
- "Please install microdf with the 'charts' extra by running " +
25
- "'pip install microdf[charts]'"
28
+ "The function you've called requires extra dependencies. "
29
+ + "Please install microdf with the 'charts' extra by running "
30
+ + "'pip install microdf[charts]'"
26
31
  )
27
32
 
28
33
  prefix = {"USD": "$", "GBP": "£"}[currency]
microdf/charts.py CHANGED
@@ -1,9 +1,18 @@
1
1
  import numpy as np
2
+ import pandas as pd
2
3
 
3
4
  import microdf as mdf
4
5
 
5
6
 
6
- def quantile_pct_chg_plot(df1, df2, col1, col2, w1=None, w2=None, q=None):
7
+ def quantile_pct_chg_plot(
8
+ df1: pd.DataFrame,
9
+ df2: pd.DataFrame,
10
+ col1: str,
11
+ col2: str,
12
+ w1: str = None,
13
+ w2: str = None,
14
+ q: np.ndarray = None,
15
+ ):
7
16
  """Create stem plot with percent change in decile boundaries.
8
17
 
9
18
  :param df1: DataFrame with first set of values.
@@ -14,17 +23,16 @@ def quantile_pct_chg_plot(df1, df2, col1, col2, w1=None, w2=None, q=None):
14
23
  :param w2: Name of weight column in df2.
15
24
  :param q: Quantiles. Defaults to decile boundaries.
16
25
  :returns: Axis.
17
-
18
26
  """
19
27
  try:
20
- import seaborn as sns
21
28
  import matplotlib as mpl
22
29
  import matplotlib.pyplot as plt
30
+ import seaborn as sns
23
31
  except ImportError:
24
32
  raise ImportError(
25
- "The function you've called requires extra dependencies. " +
26
- "Please install microdf with the 'charts' extra by running " +
27
- "'pip install microdf[charts]'"
33
+ "The function you've called requires extra dependencies. "
34
+ + "Please install microdf with the 'charts' extra by running "
35
+ + "'pip install microdf[charts]'"
28
36
  )
29
37
 
30
38
  if q is None:
@@ -41,9 +49,7 @@ def quantile_pct_chg_plot(df1, df2, col1, col2, w1=None, w2=None, q=None):
41
49
  )
42
50
  # Plot.
43
51
  fig, ax = plt.subplots()
44
- markerline, stemlines, baseline = ax.stem(
45
- df.index_newline, df.pct_chg
46
- )
52
+ markerline, stemlines, baseline = ax.stem(df.index_newline, df.pct_chg)
47
53
  plt.setp(baseline, color="gray", linewidth=0)
48
54
  ax.yaxis.set_major_locator(mpl.ticker.MaxNLocator(integer=True))
49
55
  ax.yaxis.set_major_formatter(mpl.ticker.PercentFormatter(xmax=100))
microdf/concat.py CHANGED
@@ -1,12 +1,15 @@
1
- import pandas as pd
2
1
  import inspect
2
+
3
+ import pandas as pd
4
+
3
5
  import microdf as mdf
6
+ from microdf.generic import MicroDataFrame
4
7
 
5
8
 
6
- def concat(*args, **kwargs):
7
- """Concatenates MicroDataFrame objects, preserving weights.
8
- If concatenating horizontally, the first set of weights are used.
9
- All args and kwargs are passed to pd.concat.
9
+ def concat(*args, **kwargs) -> "MicroDataFrame":
10
+ """Concatenates MicroDataFrame objects, preserving weights. If
11
+ concatenating horizontally, the first set of weights are used. All args and
12
+ kwargs are passed to pd.concat.
10
13
 
11
14
  :return: MicroDataFrame with concatenated weights.
12
15
  :rtype: mdf.MicroDataFrame
microdf/custom_taxes.py CHANGED
@@ -1,13 +1,14 @@
1
- """
2
- Functions and data for estimating taxes outside the income tax system.
1
+ """Functions and data for estimating taxes outside the income tax system.
2
+
3
3
  Examples include value added tax, financial transaction tax, and carbon tax.
4
4
  """
5
5
 
6
- import microdf as mdf
6
+ from typing import Optional
7
7
 
8
8
  import numpy as np
9
9
  import pandas as pd
10
10
 
11
+ import microdf as mdf
11
12
 
12
13
  # Source:
13
14
  # https://www.taxpolicycenter.org/briefing-book/who-would-bear-burden-vat
@@ -35,24 +36,24 @@ FTT_INCIDENCE /= 100
35
36
 
36
37
 
37
38
  def add_custom_tax(
38
- df,
39
- segment_income,
40
- w,
41
- base_income,
42
- incidence,
43
- name,
44
- total=None,
45
- ratio=None,
46
- verbose=True,
47
- ):
39
+ df: pd.DataFrame,
40
+ segment_income: str,
41
+ w: str,
42
+ base_income: str,
43
+ incidence: pd.Series,
44
+ name: str,
45
+ total: Optional[float] = None,
46
+ ratio: Optional[float] = None,
47
+ verbose: Optional[bool] = True,
48
+ ) -> None:
48
49
  """Add a custom tax based on incidence analysis driven by percentiles.
49
50
 
50
51
  :param df: DataFrame.
51
52
  :param segment_income: Income measure used to segment tax units into
52
- quantiles.
53
+ quantiles.
53
54
  :param w: Weight used to segment into quantiles (either s006 or XTOT_m).
54
55
  :param base_income: Income measure by which incidence is multiplied to
55
- estimate liability.
56
+ estimate liability.
56
57
  :param incidence: pandas Series indexed on the floor of an income
57
58
  percentile, with values for the tax rate.
58
59
  :param name: Name of the column to add.
@@ -60,13 +61,12 @@ def add_custom_tax(
60
61
  liabilities are calculated only based on the incidence schedule.
61
62
  (Default value = None)
62
63
  :param ratio: Ratio to adjust the tax by, compared to the original tax.
63
- This acts as a multiplier for the incidence argument.
64
- (Default value = None)
64
+ This acts as a multiplier for the incidence argument. (Default value =
65
+ None)
65
66
  :param verbose: Whether to print the tax adjustment factor if needed.
66
67
  Defaults to True.
67
68
  :returns: Nothing. Adds the column name to df representing the tax
68
69
  liability. df is also sorted by segment_income.
69
-
70
70
  """
71
71
  if ratio is not None:
72
72
  incidence = incidence * ratio
@@ -95,14 +95,14 @@ def add_custom_tax(
95
95
 
96
96
 
97
97
  def add_vat(
98
- df,
99
- segment_income="tpc_eci",
100
- w="XTOT_m",
101
- base_income="aftertax_income",
102
- incidence=VAT_INCIDENCE,
103
- name="vat",
104
- **kwargs
105
- ):
98
+ df: pd.DataFrame,
99
+ segment_income: Optional[str] = "tpc_eci",
100
+ w: Optional[str] = "XTOT_m",
101
+ base_income: Optional[str] = "aftertax_income",
102
+ incidence: Optional[pd.Series] = VAT_INCIDENCE,
103
+ name: Optional[str] = "vat",
104
+ **kwargs,
105
+ ) -> None:
106
106
  """Add value added tax based on incidence estimate from Tax Policy Center.
107
107
 
108
108
  :param df: DataFrame with columns for tpc_eci, XTOT_m, and aftertax_income.
@@ -111,11 +111,9 @@ def add_vat(
111
111
  :param w: Default value = "XTOT_m")
112
112
  :param base_income: Default value = "aftertax_income")
113
113
  :param incidence: Default value = VAT_INCIDENCE)
114
- :param name: Default value = "vat")
115
- :param **kwargs: Other arguments passed to add_custom_tax().
116
- :returns: Nothing. Adds vat to df.
117
- df is also sorted by tpc_eci.
118
-
114
+ :param name: Default value = "vat") :param **kwargs: Other arguments passed
115
+ to add_custom_tax().
116
+ :returns: Nothing. Adds vat to df. df is also sorted by tpc_eci.
119
117
  """
120
118
  add_custom_tax(
121
119
  df, segment_income, w, base_income, incidence, name, **kwargs
@@ -123,14 +121,14 @@ def add_vat(
123
121
 
124
122
 
125
123
  def add_carbon_tax(
126
- df,
127
- segment_income="tpc_eci",
128
- w="XTOT_m",
129
- base_income="aftertax_income",
130
- incidence=CARBON_TAX_INCIDENCE,
131
- name="carbon_tax",
132
- **kwargs
133
- ):
124
+ df: pd.DataFrame,
125
+ segment_income: Optional[str] = "tpc_eci",
126
+ w: Optional[str] = "XTOT_m",
127
+ base_income: Optional[str] = "aftertax_income",
128
+ incidence: Optional[pd.Series] = CARBON_TAX_INCIDENCE,
129
+ name: Optional[str] = "carbon_tax",
130
+ **kwargs,
131
+ ) -> None:
134
132
  """Add carbon tax based on incidence estimate from the US Treasury
135
133
  Department.
136
134
 
@@ -140,11 +138,9 @@ def add_carbon_tax(
140
138
  :param w: Default value = "XTOT_m")
141
139
  :param base_income: Default value = "aftertax_income")
142
140
  :param incidence: Default value = CARBON_TAX_INCIDENCE)
143
- :param name: Default value = "carbon_tax")
144
- :param **kwargs: Other arguments passed to add_custom_tax().
145
- :returns: Nothing. Adds carbon_tax to df.
146
- df is also sorted by tpc_eci.
147
-
141
+ :param name: Default value = "carbon_tax") :param **kwargs: Other arguments
142
+ passed to add_custom_tax().
143
+ :returns: Nothing. Adds carbon_tax to df. df is also sorted by tpc_eci.
148
144
  """
149
145
  add_custom_tax(
150
146
  df, segment_income, w, base_income, incidence, name, **kwargs
@@ -152,14 +148,14 @@ def add_carbon_tax(
152
148
 
153
149
 
154
150
  def add_ftt(
155
- df,
156
- segment_income="tpc_eci",
157
- w="XTOT_m",
158
- base_income="aftertax_income",
159
- incidence=FTT_INCIDENCE,
160
- name="ftt",
161
- **kwargs
162
- ):
151
+ df: pd.DataFrame,
152
+ segment_income: Optional[str] = "tpc_eci",
153
+ w: Optional[str] = "XTOT_m",
154
+ base_income: Optional[str] = "aftertax_income",
155
+ incidence: Optional[pd.Series] = FTT_INCIDENCE,
156
+ name: Optional[str] = "ftt",
157
+ **kwargs,
158
+ ) -> None:
163
159
  """Add financial transaction tax based on incidence estimate from Tax
164
160
  Policy Center.
165
161
 
@@ -169,11 +165,9 @@ def add_ftt(
169
165
  :param w: Default value = "XTOT_m")
170
166
  :param base_income: Default value = "aftertax_income")
171
167
  :param incidence: Default value = FTT_INCIDENCE)
172
- :param name: Default value = "ftt")
173
- :param **kwargs: Other arguments passed to add_custom_tax().
174
- :returns: Nothing. Adds ftt to df.
175
- df is also sorted by tpc_eci.
176
-
168
+ :param name: Default value = "ftt") :param **kwargs: Other arguments passed
169
+ to add_custom_tax().
170
+ :returns: Nothing. Adds ftt to df. df is also sorted by tpc_eci.
177
171
  """
178
172
  add_custom_tax(
179
173
  df, segment_income, w, base_income, incidence, name, **kwargs