Estoy en busca de una tercera parte, lib, que tiene la siguiente if-prueba:

if isinstance(xx_, numpy.ndarray) and xx_.dtype is numpy.float64 and xx_.flags.contiguous:
    xx_[:] = ctypes.cast(xx_.ctypes._as_parameter_,ctypes.POINTER(ctypes.c_double))

Parece que xx_.dtype is numpy.float64 siempre falla:

>>> xx_ = numpy.zeros(8, dtype=numpy.float64)
>>> xx_.dtype is numpy.float64

False

¿Cuál es la forma correcta para probar que el dtype de una colección que la matriz es float64 ?

  • En primer lugar, ¿por qué tienes tanto numpy y np en el mismo script? ¿Hay alguna posibilidad de que ellos son diferentes copias del módulo? (Trate de numpy is np a ver…)
  • error – fijo ahora. Que posteriormente ejemplo es sólo para demostrar una prueba que muestra la comparación siempre falla, no forma parte de la tercera parte lib
  • Como, a continuación, que realmente no se necesita probar la misma cosa en mi respuesta que ya sabía, y podría haber hecho más corto. Oh, bueno. 🙂
  • Si no es demasiada molestia, podrías editar la respuesta a proporcionar la forma correcta de hacer la prueba? Creo que voy a editar mi pregunta para hacer que más el foco, como hacer la prueba correctamente, va a ser de más interés para cualquiera que esté buscando en esta cuestión en el futuro.
  • No estoy 100% seguro de lo que es el derecho de la prueba es. Probablemente ==, pero, sin saber por qué es la comprobación, no puede ser. Voy a tratar de escribir la respuesta a transmitir eso.
InformationsquelleAutor Zero | 2014-11-14

2 Comentarios

  1. 21

    Este es un error en el lib.

    dtype objetos puede ser construido de forma dinámica. Y NumPy lo hace todo el tiempo. No hay ninguna garantía de cualquier lugar que están internados, por lo que la construcción de un dtype que ya existe le dará la misma.

    En la parte superior de que, np.float64 no es en realidad un dtype; es un… no sé lo que estos tipos son los llamados, pero los tipos utilizados para la construcción de escalar objetos de la matriz de bytes, que se encuentran generalmente en el type atributo de un dtype, así que voy a llamar a un dtype.type. (Tenga en cuenta que np.float64 subclases tanto NumPy numérico de tipo torre y el de Python numérico de la torre de Abc, mientras que np.dtype por supuesto que no.)

    Normalmente, puede usar estas indistintamente; cuando se utiliza un dtype.type—o, para el caso, un nativo de Python tipo numérico—donde un dtype era de esperar, un dtype se construye sobre la marcha (que, de nuevo, no está garantizado a ser internado), pero por supuesto eso no significa que sean idénticos:

    >>> np.float64 == np.dtype(np.float64) == np.dtype('float64') 
    True
    >>> np.float64 == np.dtype(np.float64).type
    True

    La dtype.type generalmente se ser idénticos si usted está usando builtin tipos:

    >>> np.float64 is np.dtype(np.float64).type
    True

    Pero dos dtypes a menudo no son:

    >>> np.dtype(np.float64) is np.dtype('float64')
    False

    Pero de nuevo, nada de eso está garantizado. (También, tenga en cuenta que np.float64 y float usar exactamente el mismo de almacenamiento, pero son independientes de los tipos. Y, por supuesto, usted también puede hacer un dtype('f8'), que está garantizado para trabajar de la misma como dtype(np.float64), pero eso no significa que 'f8' is, o incluso ==, np.float64.)

    Así, es posible que la construcción de una matriz se pasa explícitamente np.float64 como su dtype argumento significa que usted recibe de vuelta la misma instancia cuando se compruebe que la dtype.type atributo, pero eso no está garantizado. Y si pasa np.dtype('float64'), o de pedir NumPy para inferir de los datos, o pasar un dtype cadena para analizar como 'f8', etc., es aún menos probable que coincida. Lo que es más importante, usted definitivamente no obtener np.float64 como el dtype sí mismo.


    Así que, ¿cómo debe ser fijo?

    Bien, el docs definir lo que significa para dos dtypes igual, y eso es una cosa útil, y creo que es probablemente la cosa útil que usted está buscando aquí. Así, basta con sustituir el is con ==:

    if isinstance(xx_, numpy.ndarray) and xx_.dtype == numpy.float64 and xx_.flags.contiguous:

    Sin embargo, en cierta medida, sólo estoy adivinando que es lo que estás buscando. (El hecho de que es la comprobación de los estados de la bandera implica que probablemente va a ir a la derecha en el almacenamiento interno… pero entonces, ¿por qué no es la comprobación de C frente a Fortran orden o de orden de bytes, o cualquier otra cosa?)

  2. 1

    Tratar:

    x = np.zeros(8, dtype=np.float64)
    print x.dtype is np.dtype(np.float64))    

    is pruebas de la identidad de los 2 objetos, si tienen el mismo id(). Se utiliza por ejemplo para probar is None, pero puede dar errores en las pruebas para enteros o cadenas de caracteres. Pero en este caso, hay un problema adicional, x.dtype y np.float64 no son de la misma clase.

    isinstance(x.dtype, np.dtype)  # True
    isinstance(np.float64, np.dtype) # False
    
    
    x.dtype.__class__  # numpy.dtype
    np.float64.__class__ # type

    np.float64 en realidad es una función. np.float64() produce 0.0. x.dtype() produce un error. (corrección de np.float64 es una clase).

    En mis pruebas interactivas:

    x.dtype is np.dtype(np.float64)

    devuelve True. Pero no sé si eso es universalmente el caso, o simplemente el resultado de algún tipo de almacenamiento en caché local. El dtype documentación menciona un dtype atributo:

    dtype.num de Un número único para cada una de las 21 diferentes tipos integrados.

    Tanto dtypes dar 12 para este num.

    x.dtype == np.float64

    pruebas True.

    Además, el uso de type obras:

    x.dtype.type is np.float64  # True

    Cuando puedo importar ctypes y hacer el cast (con su xx_) me sale un error:

    ValueError: la configuración de un elemento de la matriz con una secuencia.

    No sé lo suficiente de ctypes para entender lo que está tratando de hacer. Parece que está haciendo un tipo de conversión de la data puntero de xx_, xx_.ctypes._as_parameter_ es el mismo número que xx_.__array_interface__['data'][0].


    En el numpy código de prueba me parece que estos dtype pruebas:

    issubclass(arr.dtype.type, (nt.integer, nt.bool_)
    assert_(dat.dtype.type is np.float64)
    assert_equal(A.dtype.type, np.unicode_)
    assert_equal(r['col1'].dtype.kind, 'i')

    numpy documentación también habla sobre

    np.issubdtype(x.dtype, np.float64)
    np.issubsctype(x, np.float64)

    tanto de que el uso de issubclass.


    Aún más el seguimiento de la c código sugiere que x.dtype == np.float64 se evalúa como:

    x.dtype.num == np.dtype(np.float64).num

    Que es, el tipo escalar se convierte en un dtype, y el .num atributos de comparación. El código está en scalarapi.c, descriptor.c, multiarraymodule.c de numpy /core /src /multiarray

    • Hay alguna información útil aquí. Es cierto que una dtype tiene un type, que es la clase que se usa para construir los escalares de la clase, y no el mismo que el dtype sí mismo, y que float64 es el último, no el primero. Por otro lado, no es cierto que la float64 en realidad es una función (el hecho de que su tipo es type demuestra que). Y por lo general, puede usar un dtype.type dondequiera que usted puede utilizar un dtype; haciendo así que solo construye un nuevo dtype objeto sobre la marcha. Tenga en cuenta que dtype('float64') == dtype(float64) == float64. Y creo que la última es la clave para lo que el OP se preocupa por aquí.
    • OK, `np.float64′ no es una función. Iba a clase que se puede llamar ser más preciso?
    • Bien, todo las clases se puede llamar. No entiendo cuál es el contraste que usted está apuntando para allí.
    • Estás en lo correcto. Yo estaba pensando en la clase de objetos que se puede llamar, que no es el caso aquí. Estoy tratando de definir la diferencia entre un type como float64 y un dtype. ¿Sabes dónde está el __eq__ para dtype se define (o su equivalente en c código)?
    • Para el primer semestre, la diferencia es que un float64 es un tipo numérico. No sé cuál es el término adecuado para aquellos que es, pero es similar a la builtin float (de hecho, casi intercambiables con él; si mal no recuerdo, es sólo una subclase que también hereda de la NumPy numérico tipo torre) o int. De la misma manera usted puede construir np.dtype(float), usted puede construir np.dtype(float64). Y de la misma manera que sólo se puede pasar float en cualquier lugar de una dtype se espera, usted puede pasar float64.
    • Para la segunda mitad, creo que es arraydescr_richcompare, que sólo se pospone para el NumPy público-función de la API de PyArray_EquivTypes, pero que desde un análisis rápido, así que no te fíes demasiado lejos…
    • Comenzando con richcompare he trazado el código y creo que el np.float64 tipo está envuelto en dtype, y el .num atributos de la comparación.
    • Sí, si mal no recuerdo, la comparación de un dtype a cualquier otra cosa que construye un dtype de que cualquier otra cosa; entonces, si tanto dtypes son numpy tipos o nativo de Python tipos, son comparados por numpy tipo de números o Python tipo de objetos. De todos modos, creo que es más importante averiguar lo que está documentado (y por lo tanto probable que sea el mismo entre 1.8 y 1.9, NumPy y NumPyPy, diferentes builds/plataformas, etc.) de cómo se implementa, a menos que usted está realmente escrito implementación a nivel de código.

Dejar respuesta

Please enter your comment!
Please enter your name here