Skip to content

Commit

Permalink
As of date parameters (#1212)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjello committed Aug 3, 2024
2 parents 8e28b0d + bc4ac9e commit 8c6bc57
Show file tree
Hide file tree
Showing 10 changed files with 538 additions and 2 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Changelog

### 41.4.7 [#1212](https://github.com/openfisca/openfisca-core/pull/1212)
## 41.5.0 [#1212](https://github.com/openfisca/openfisca-core/pull/1212)

#### New features

- Introduce `VectorialAsofDateParameterNodeAtInstant`
- It is a parameter node of the legislation at a given instant which has been vectorized along some date.
- Vectorized parameters allow requests such as parameters.housing_benefit[date], where date is a `numpy.datetime64` vector

### 41.4.7 [#1211](https://github.com/openfisca/openfisca-core/pull/1211)

#### Technical changes

Expand Down
2 changes: 2 additions & 0 deletions openfisca_core/parameters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from .parameter_scale_bracket import ParameterScaleBracket
from .parameter_scale_bracket import ParameterScaleBracket as Bracket
from .values_history import ValuesHistory
from .vectorial_asof_date_parameter_node_at_instant import VectorialAsofDateParameterNodeAtInstant
from .vectorial_parameter_node_at_instant import VectorialParameterNodeAtInstant

__all__ = [
Expand All @@ -63,5 +64,6 @@
"ParameterScaleBracket",
"Bracket",
"ValuesHistory",
"VectorialAsofDateParameterNodeAtInstant",
"VectorialParameterNodeAtInstant",
]
4 changes: 4 additions & 0 deletions openfisca_core/parameters/parameter_node_at_instant.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __getattr__(self, key):
def __getitem__(self, key):
# If fancy indexing is used, cast to a vectorial node
if isinstance(key, numpy.ndarray):
# If fancy indexing is used wit a datetime64, cast to a vectorial node supporting datetime64
if numpy.issubdtype(key.dtype, numpy.datetime64):
return parameters.VectorialAsofDateParameterNodeAtInstant.build_from_node(self)[key]

return parameters.VectorialParameterNodeAtInstant.build_from_node(self)[key]
return self._children[key]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import numpy

from openfisca_core.parameters.parameter_node_at_instant import ParameterNodeAtInstant
from openfisca_core.parameters.vectorial_parameter_node_at_instant import VectorialParameterNodeAtInstant


class VectorialAsofDateParameterNodeAtInstant(VectorialParameterNodeAtInstant):
"""
Parameter node of the legislation at a given instant which has been vectorized along some date.
Vectorized parameters allow requests such as parameters.housing_benefit[date], where date is a np.datetime64 type vector
"""

@staticmethod
def build_from_node(node):
VectorialParameterNodeAtInstant.check_node_vectorisable(node)
subnodes_name = node._children.keys()
# Recursively vectorize the children of the node
vectorial_subnodes = tuple([
VectorialAsofDateParameterNodeAtInstant.build_from_node(node[subnode_name]).vector
if isinstance(node[subnode_name], ParameterNodeAtInstant)
else node[subnode_name]
for subnode_name in subnodes_name
])
# A vectorial node is a wrapper around a numpy recarray
# We first build the recarray
recarray = numpy.array(
[vectorial_subnodes],
dtype=[
(subnode_name, subnode.dtype if isinstance(subnode, numpy.recarray) else 'float')
for (subnode_name, subnode) in zip(subnodes_name, vectorial_subnodes)
]
)
return VectorialAsofDateParameterNodeAtInstant(node._name, recarray.view(numpy.recarray), node._instant_str)

def __getitem__(self, key):
# If the key is a string, just get the subnode
if isinstance(key, str):
key = numpy.array([key], dtype='datetime64[D]')
return self.__getattr__(key)
# If the key is a vector, e.g. ['1990-11-25', '1983-04-17', '1969-09-09']
elif isinstance(key, numpy.ndarray):
assert numpy.issubdtype(key.dtype, numpy.datetime64)
names = list(self.dtype.names) # Get all the names of the subnodes, e.g. ['before_X', 'after_X', 'after_Y']
values = numpy.asarray([value for value in self.vector[0]])
names = [
name
for name in names
if not name.startswith("before")
]
names = [
numpy.datetime64(
"-".join(name[len("after_"):].split("_"))
)
for name in names
]
conditions = sum([
name <= key
for name in names
])
result = values[conditions]

# If the result is not a leaf, wrap the result in a vectorial node.
if numpy.issubdtype(result.dtype, numpy.record) or numpy.issubdtype(result.dtype, numpy.void):
return VectorialAsofDateParameterNodeAtInstant(self._name, result.view(numpy.recarray), self._instant_str)

return result
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@

setup(
name="OpenFisca-Core",
version="41.4.7",
version="41.5.0",
author="OpenFisca Team",
author_email="contact@openfisca.org",
classifiers=[
Expand Down
Empty file.
121 changes: 121 additions & 0 deletions tests/core/parameters_date_indexing/full_rate_age.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
description: Full rate age
full_rate_age_by_birthdate:
description: Full rate age by birthdate
before_1951_07_01:
description: Born before 01/07/1951
year:
description: Year
values:
1983-04-01:
value: 65.0
month:
description: Month
values:
1983-04-01:
value: 0.0
after_1951_07_01:
description: Born after 01/07/1951
year:
description: Year
values:
2011-07-01:
value: 65.0
1983-04-01:
value: null
month:
description: Month
values:
2011-07-01:
value: 4.0
1983-04-01:
value: null
after_1952_01_01:
description: Born after 01/01/1952
year:
description: Year
values:
2011-07-01:
value: 65.0
1983-04-01:
value: null
month:
description: Month
values:
2012-01-01:
value: 9.0
2011-07-01:
value: 8.0
1983-04-01:
value: null
after_1953_01_01:
description: Born after 01/01/1953
year:
description: Year
values:
2011-07-01:
value: 66.0
1983-04-01:
value: null
month:
description: Month
values:
2012-01-01:
value: 2.0
2011-07-01:
value: 0.0
1983-04-01:
value: null
after_1954_01_01:
description: Born after 01/01/1954
year:
description: Year
values:
2011-07-01:
value: 66.0
1983-04-01:
value: null
month:
description: Month
values:
2012-01-01:
value: 7.0
2011-07-01:
value: 4.0
1983-04-01:
value: null
after_1955_01_01:
description: Born after 01/01/1955
year:
description: Year
values:
2012-01-01:
value: 67.0
2011-07-01:
value: 66.0
1983-04-01:
value: null
month:
description: Month
values:
2012-01-01:
value: 0.0
2011-07-01:
value: 8.0
1983-04-01:
value: null
after_1956_01_01:
description: Born after 01/01/1956
year:
description: Year
values:
2011-07-01:
value: 67.0
1983-04-01:
value: null
month:
description: Month
values:
2011-07-01:
value: 0.0
1983-04-01:
value: null
Loading

0 comments on commit 8c6bc57

Please sign in to comment.