-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Corrige zone_logement_social pour retourner un vecteur #1395
Conversation
6da13d6
to
a95250d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je recommanderais plutôt de dépublier la version de Core qui a causé la régression, puis d'analyser ce qui est nécessaire pour la compatibilité avec Numpy. Je trouve aussi qu'introduire Mypy n'est pas pertinent car en dehors du scope de cette PR.
@maukoquiroga : j'ai corrigé le test qui passe maintenant avec la version de core master et la version de la PR openfisca/openfisca-core#923. Je te laisse choisir avec @Morendil la stratégie adéquate. |
Merci @Morendil
👍
Tu dis appart de l'utilisation de
La première chose que j'ai faite pour cibler le problème est de faire une hypothèse de signature. Je trouve donc au moins les annotations de type utiles, même si le type checking n'est effectivement pas nécessaire (or j'ai l'ai utilisé dans la cadre de cette PR). Tu dis d'enlever MyPy lui-même ou les annotations aussi ? |
@Morendil en suivant tes conseils, j'ai fait une analyse de compatibilité OpenFisca Core avec Numpy 1.18 : openfisca/openfisca-core#924. Bien que le code concerné par le changement utilise quasi-exclusivement TODO :
Au-delà de ces considérations, cette PR reste d'actualité, j'actualise juste la description. Merci! |
A mon sens ce n'est pas une question de scalaire ou de vecteur; la version 1.18 de Numpy a supprimé la possibilité d'utiliser des entiers dans les vecteurs fournis à C'est moins la compatibilité de Core avec Numpy 1.18 qui me pose souci que la compatibilité de France, et par extension des autres pays. Cela me mettait mal à l'aise de savoir que dans beaucoup d'endroits dans France on utilise des sommes ou des multiplications pour manipuler des valeurs logiques; sachant cela je me serais attendu à ce que le problème soit beaucoup plus étendu. Je suis agréablement surpris que la formule de A mon avis il vaut mieux utiliser |
in_paris_communes_limitrophes = sum([depcom == commune_proche_paris for commune_proche_paris in paris_communes_limitrophes]) | ||
in_idf = sum([startswith(depcom, departement) for departement in departements_idf]) | ||
in_paris_communes_limitrophes = array( | ||
sum( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Utiliser np.logical_or.reduce
; les array depcom == …
sont de type booléen, c'est dommage de les forcer en valeurs entières puis refaire l'opération inverse.
in_paris_communes_limitrophes = np.logical_or.reduce([depcom == commune_proche_paris
for commune_proche_paris in paris_communes_limitrophes])
…mais d'ailleurs est-ce que Numpy ne propose pas une primitive pour tester l'appartenance d'une valeur à un ensemble ou à une liste ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merci ! Si j'ai bien compris
np.logical_or.reduce
est l'équivalent de
np.any_(foo, axis = 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…oui mais comme je le disais plus haut il est encore préférable d'utiliser np.isin
que je découvre à l'instant dans Numpy:
>>> import numpy as np
>>> test_values = [3,5,7]
>>> a = np.array([1,2,3,4,5,6,7,8,9,10])
>>> np.logical_or.reduce([a == v for v in test_values])
array([False, False, True, False, True, False, True, False, False, False])
>>> np.isin(a,test_values)
array([False, False, True, False, True, False, True, False, False, False])
…soit dans notre cas:
np.isin(depcom, paris_communes_limitrophes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Soit l'exemple complet :
in_paris_communes_limitrophes = isin(depcom, paris_communes_limitrophes)
in_idf = isin([True], startswith(depcom, departements_idf))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in_idf = isin([True], startswith(depcom, departements_idf))
Je pense que ce n'est pas correct. isin
va renvoyer un vecteur de la même taille que son premier argument, donc un seul élément dans la formulation ci-dessus, même si le vecteur depcom
a une taille différente de 1.
Là encore il vaut mieux utiliser une opération Numpy (vectorisée) sur les chaines, à la place de l'opération correspondante en Python; en fait ce qu'on veut c'est les 2 premiers caractères de depcom
, qui correspondent au département. C'est numpy.char.ljust
.
>>> a = np.array(["93451","75001","45001"])
>>> np.isin(np.char.ljust(a,2),["93","75"])
array([ True, True, False])
Donc
in_idf = np.isin(np.char.ljust(depcom,2), departements_idf)
Tout ça me fait penser au passage à openfisca/openfisca-core#673 - on a eu tendance à sous-estimer l'importance pour les utilisateurs de comprendre le calcul vectoriel en général et Numpy en particulier.
Pour cette raison d'ailleurs je suis plus favorable à l'import en bloc import numpy as np
(ou même comme recommandé par Matti import numpy
) de préférence à l'import sélectif from numpy import (isin, char, …)
de façon à mettre en évidence les portions du code qui appellent les primitives Numpy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in_idf = np.isin(np.char.ljust(depcom,2), departements_idf)
👍
Pour cette raison d'ailleurs je suis plus favorable à l'import en bloc import numpy as np (ou même comme recommandé par Matti import numpy) de préférence à l'import sélectif from numpy import (isin, char, …)
C'est pour cela que j'essaie d'éviter les imports globaux :
from openfisca_france.model.base import *
Concernant l'import du module vs. l'import selectif, après lire cet article, je suis d'accord.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JE suis aussi pour virer les import globaux aussi souvent que possible
@maukoquiroga : je garderais l'ancienne convention de passer par des alias raccourcis ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Voir mon commentaire (désolé).
04939f8
to
b1ff8e0
Compare
fca398d
to
2469a00
Compare
Fixes #1394
model/prestations/logement_social.py
.numpy.ndarray[int]
.numpy.ndarray[bool]
.select
avec un valeur nonbool
est dépréciée.Ces changements :
Quelques conseils à prendre en compte :
setup.py
.CHANGELOG.md
.