J'ai un rang 1 numpy.array
dont je veux faire un boxplot. Cependant, je veux exclure toutes les valeurs égales à zéro dans le tableau. Actuellement, j'ai résolu cela en bouclant le tableau et en copiant la valeur dans un nouveau tableau s'il n'est pas égal à zéro. Cependant, comme le tableau se compose de 86 000 000 de valeurs et que je dois le faire plusieurs fois, cela demande beaucoup de patience.
Existe-t-il une façon plus intelligente de procéder?
C'est un cas où vous souhaitez utiliser des tableaux masqués, il conserve la forme de votre tableau et il est automatiquement reconnu par toutes les fonctions numpy et matplotlib.
X = np.random.randn(1e3, 5)
X[np.abs(X)< .1]= 0 # some zeros
X = np.ma.masked_equal(X,0)
plt.boxplot(X) #masked values are not plotted
#other functionalities of masked arrays
X.compressed() # get normal array with masked values removed
X.mask # get a boolean array of the mask
X.mean() # it automatically discards masked values
Pour un tableau NumPy a
, vous pouvez utiliser
a[a != 0]
pour extraire les valeurs différentes de zéro.
Une simple ligne de code peut vous procurer un tableau qui exclut toutes les valeurs "0":
np.argwhere(*array*)
exemple:
import numpy as np
array = [0, 1, 0, 3, 4, 5, 0]
array2 = np.argwhere(array)
print array2
[1, 3, 4, 5]
Je voudrais vous suggérer d'utiliser simplement NaN
pour des cas comme celui-ci, où vous aimerez ignorer certaines valeurs, tout en gardant la statistique statistique aussi significative que possible. Alors
In []: X= randn(1e3, 5)
In []: X[abs(X)< .1]= NaN
In []: isnan(X).sum(0)
Out[: array([82, 84, 71, 81, 73])
In []: boxplot(X)
Vous pouvez indexer avec un tableau booléen. Pour un tableau NumPy A
:
res = A[A != 0]
Vous pouvez utiliser indexation de tableau booléen comme ci-dessus, conversion de type bool
, np.nonzero
, ou np.where
. Voici une analyse comparative des performances:
# Python 3.7, NumPy 1.14.3
np.random.seed(0)
A = np.random.randint(0, 5, 10**8)
%timeit A[A != 0] # 768 ms
%timeit A[A.astype(bool)] # 781 ms
%timeit A[np.nonzero(A)] # 1.49 s
%timeit A[np.where(A)] # 1.58 s
J'ai décidé de comparer le temps d'exécution des différentes approches mentionnées ici. J'ai utilisé ma bibliothèque simple_benchmark
pour cela.
L'indexation booléenne avec array[array != 0]
semble être la solution la plus rapide (et la plus courte).
Pour les tableaux plus petits, l'approche MaskedArray est très lente par rapport aux autres approches, mais elle est aussi rapide que l'approche d'indexation booléenne. Cependant, pour les tableaux de taille moyenne, il n'y a pas beaucoup de différence entre eux.
Voici le code que j'ai utilisé:
from simple_benchmark import BenchmarkBuilder
import numpy as np
bench = BenchmarkBuilder()
@bench.add_function()
def boolean_indexing(arr):
return arr[arr != 0]
@bench.add_function()
def integer_indexing_nonzero(arr):
return arr[np.nonzero(arr)]
@bench.add_function()
def integer_indexing_where(arr):
return arr[np.where(arr != 0)]
@bench.add_function()
def masked_array(arr):
return np.ma.masked_equal(arr, 0)
@bench.add_arguments('array size')
def argument_provider():
for exp in range(3, 25):
size = 2**exp
arr = np.random.random(size)
arr[arr < 0.1] = 0 # add some zeros
yield size, arr
r = bench.run()
r.plot()