Numpy: Sortie inattendue de arange avec dtype = int

Créé le 5 mai 2020  ·  5Commentaires  ·  Source: numpy/numpy


Dans [3]: np.arange (-3, 0, 0.5, dtype = int)
Sortie [3]: tableau ([- 3, -2, -1, 0, 1, 2])

Eh bien, voir un "1" et un "2" était un peu inattendu pour nous puisque les deux nombres sont un peu plus grands que 0.

Normalement, c'est le résultat sans dtype = int:

In [2]: np.arange(-3, 0, 0.5)                                                  
Out[2]: array([-3. , -2.5, -2. , -1.5, -1. , -0.5])
and we should get this with dtype=int:
In [4]: np.arange(-3, 0, 0.5).astype(int)                                      
Out[4]: array([-3, -2, -2, -1, -1,  0])

Le manuel numpy déclare:
dtype: dtype
Le type du tableau de sortie. Si dtype n'est pas donné, déduire le type de données à partir des autres arguments d'entrée.

Ainsi, cela ne devrait affecter que le tableau de sortie, non?

import numpy as np
print(np.arange(-3, 0, 0.5))
print(np.arange(-3, 0, 0.5, dtype=int))
print(np.arange(-3, 0, 0.5).astype(int))

Message d'erreur:

Aucun message d'erreur ...

Informations sur la version Numpy / Python:

Nous l'avons testé sous numpy '1.18.4' (pur Python 3.7.6) ainsi que '1.18.1' (Anaconda 3.7 avec la dernière mise à jour appliquée). Même résultat.

1.18.4 3.7.6 (par défaut, 28 février 2020, 15:25:38)
[Clang 11.0.0 ( https://github.com/llvm/llvm-project.git eefbff0082c5228e01611f7

1.18.1 3.7.4 (par défaut, 13 août 2019, 20:35:49)
[GCC 7.3.0]

00 - Bug numpy.core

Commentaire le plus utile

Obtenir des valeurs plus grandes que "stop" n'est vraiment pas agréable et un peu inattendu. Si arange n'est pas pour float, vous pouvez vérifier les types floaty numpy et lever une exception.

De plus, l'entrée manuelle pour dtype permet vraiment à l'utilisateur de s'attendre à quelque chose comme une conversion astype (dtype) de la sortie uniquement.

Que diriez-vous:
1.) Exception pour les arguments non entiers (ie start, stop, step).
2.) Vérifiez si stop> = start, sinon soulevez une exception
3.) Lancer démarrer, arrêter, passer à int64 au début de la fonction.
4.) astype (dtype) la sortie

Au lieu de 1.), vous pouvez rediriger vers linspace à l'intérieur de arange si une entrée non entière est trouvée.

Tous les 5 commentaires

Des bogues comme celui-ci sont signalés à maintes reprises. Pour des raisons perdues dans le temps, je suis assez convaincu que l'implémentation d'arange est quelque chose comme:

def arange(start, stop, step, dtype):
    n = (start - stop) // step

    # dtype.type is a cast
    step = dtype.type(start + step) - dtype.type(start)

    # now do what you expect
    return [start + step*i for i in range(n)]

Peut-être devrions-nous ajouter ce pseudo-code à la documentation?

Ouais, ce code est correct (pas sûr à 100% du calcul n cependant). Cet exemple spécifique est assez extrême et évidemment cassé, peut-être pouvons-nous nous en débarrasser d'une manière ou d'une autre?

arange est détesté à plusieurs reprises pour la définition sans doute cassée, mais je ne peux pas penser à une très bonne proposition pour y remédier (même si peut-être en a-t-on déjà eu une).
Ce n'est pas comme si nous pouvions bien changer le comportement de arange pour les flottants (peut-être des corrections de précision, mais les changements de point final ne sont pas bons pour l'OMI). Nous aurions donc besoin de créer une nouvelle fonction ... Mais dans la plupart des cas, il me semble que linspace est mieux qu'une plage de flotteurs "correcte", je ne suis pas sûr qu'une plage de flotteurs corrigée ait réellement trop de cas d'utilisation.

En fin de compte, j'imagine que j'aimerais une proposition bien pensée: / ...

Obtenir des valeurs plus grandes que "stop" n'est vraiment pas agréable et un peu inattendu. Si arange n'est pas pour float, vous pouvez vérifier les types floaty numpy et lever une exception.

De plus, l'entrée manuelle pour dtype permet vraiment à l'utilisateur de s'attendre à quelque chose comme une conversion astype (dtype) de la sortie uniquement.

Que diriez-vous:
1.) Exception pour les arguments non entiers (ie start, stop, step).
2.) Vérifiez si stop> = start, sinon soulevez une exception
3.) Lancer démarrer, arrêter, passer à int64 au début de la fonction.
4.) astype (dtype) la sortie

Au lieu de 1.), vous pouvez rediriger vers linspace à l'intérieur de arange si une entrée non entière est trouvée.

Hey, je suis un débutant complet pour la contribution open source. J'ai pensé à essayer. Et cet extrait de code? @ eric-wieser

x = []
for i in range(start, stop):
    x.append(i)
    x.append(i+step)
print(np.array(x, dtype))

Des bogues comme celui-ci sont signalés à maintes reprises. Pour des raisons perdues dans le temps, je suis assez convaincu que l'implémentation d'arange est quelque chose comme:

def arange(start, stop, step, dtype):
    n = (start - stop) // step

    # dtype.type is a cast
    step = dtype.type(start + step) - dtype.type(start)

    # now do what you expect
    return [start + step*i for i in range(n)]
Cette page vous a été utile?
0 / 5 - 0 notes