He comparado algunos de los métodos posibles para hacer esto, incluidos los pandas, varios métodos numpy y un método de comprensión de listas.
Primero, comencemos con una línea de base:
>>> import numpy as np
>>> import operator
>>> import pandas as pd
>>> x = [1, 2, 1, 2]
>>> %time count = np.sum(np.equal(1, x))
>>> print("Count {} using numpy equal with ints".format(count))
CPU times: user 52 µs, sys: 0 ns, total: 52 µs
Wall time: 56 µs
Count 2 using numpy equal with ints
Por lo tanto, nuestra línea de base es que el recuento debe ser correcto 2
y debemos tomar aproximadamente50 us
.
Ahora, probamos el método ingenuo:
>>> x = ['s', 'b', 's', 'b']
>>> %time count = np.sum(np.equal('s', x))
>>> print("Count {} using numpy equal".format(count))
CPU times: user 145 µs, sys: 24 µs, total: 169 µs
Wall time: 158 µs
Count NotImplemented using numpy equal
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel_launcher.py:1: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
"""Entry point for launching an IPython kernel.
Y aquí, obtenemos la respuesta incorrecta ( NotImplemented != 2
), nos lleva mucho tiempo y arroja la advertencia.
Entonces probaremos otro método ingenuo:
>>> %time count = np.sum(x == 's')
>>> print("Count {} using ==".format(count))
CPU times: user 46 µs, sys: 1 µs, total: 47 µs
Wall time: 50.1 µs
Count 0 using ==
Nuevamente, la respuesta incorrecta ( 0 != 2
). Esto es aún más insidioso porque no hay advertencias posteriores ( 0
se pueden transmitir de la misma manera 2
).
Ahora, intentemos una lista de comprensión:
>>> %time count = np.sum([operator.eq(_x, 's') for _x in x])
>>> print("Count {} using list comprehension".format(count))
CPU times: user 55 µs, sys: 1 µs, total: 56 µs
Wall time: 60.3 µs
Count 2 using list comprehension
Aquí obtenemos la respuesta correcta, ¡y es bastante rápido!
Otra posibilidad pandas
,:
>>> y = pd.Series(x)
>>> %time count = np.sum(y == 's')
>>> print("Count {} using pandas ==".format(count))
CPU times: user 453 µs, sys: 31 µs, total: 484 µs
Wall time: 463 µs
Count 2 using pandas ==
¡Lento, pero correcto!
Y finalmente, la opción que voy a usar: convertir la numpy
matriz al object
tipo:
>>> x = np.array(['s', 'b', 's', 'b']).astype(object)
>>> %time count = np.sum(np.equal('s', x))
>>> print("Count {} using numpy equal".format(count))
CPU times: user 50 µs, sys: 1 µs, total: 51 µs
Wall time: 55.1 µs
Count 2 using numpy equal
¡Rápido y correcto!
thing
(que puede o no ser un tipo numpy; no lo sé) y quiero ver sithing == 'some string'
y obtener unbool
resultado simple , ¿qué debo hacer?np.atleast_1d(thing)[0] == 'some string'
? Pero eso no es robusto para que algún bromista ponga'some string'
el primer elemento de una matriz. Supongo que tengo que probar el tipo dething
primero y luego solo hacer la==
prueba si es una cadena (o no un objeto numpy).