2017-07-21 2 views
2

Par exemple, j'ai un flux de tableau avec des nombres compris entre 0.0 et 10.0 inclus.Affectez rapidement un tableau à n segments de longueur égale

Je veux affecter les numéros dans arr à 5 bins de longueur égale rapidement.

Par longueur égale, je veux dire les intervalles de casiers sont [0.0, 2.0), [2.0, 4.0), [4.0, 6.0), [6.0, 8.0), [8.0, 10.0].

Le problème est que le dernier intervalle n'est pas le même que les autres intervalles.

Test:

import numpy as np 
# Things we know and can pre-calculate 
n_bins = 5 
minimal = 0.0 
maximal = 10.0 
reciprocal_bin_length = n_bins/(maximal - minimal) 

# Let's say the stream gives 1001 numbers every time. 
data = np.arange(1001)/100 

norm_data = (data - minimal) * reciprocal_bin_length 
norm_data = norm_data.astype(int) 
print(norm_data.max()) 
print(norm_data.min()) 

Résultat:

5 
0 

L'indice bin doit être 0, 1, 2, 3 ou 4, mais pas 5.

+0

Je pense que vous cherchez peut-être [numpy.digitize] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html). – Marein

+0

min est 0. max est exactement 10 de cette façon. numériser permet d'avoir une longueur inégale et peut être plus lent. c'est une longueur égale. –

+0

qu'en est-il de [pandas.cut] (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html) – jeremycg

Répondre

3

A "pauvres la solution de l'homme "pourrait être de calculer le minimum entre votre tableau norm_data et nbins-1:

norm_data = np.minimum(norm_data,nbins-1) 

Donc tous les 5 s (et plus) seront convertis en 4 s. Attention, bien sûr, ici, vous n'effectuerez pas une vérification correcte de la portée (120.0 se retrouvera également dans la case 4).

0

Si 0,1% d'erreur est acceptable, ce qui suit est un peu plus rapide. Vous ne savez pas si cela convient à l'arrondissement en virgule flottante.

import numpy as np 
# Things we know and can pre-calculate 
n_bins = 5 
minimal = 0.0 
maximal = 10.0 
approx = 1.001 # <-- this is new 
reciprocal_bin_length = n_bins/(maximal*approx - minimal) 

# Let's say the stream gives 1001 numbers every time. 
data = np.arange(1001)/100 

# can use numexpr for speed. 
norm_data = (data - minimal) * reciprocal_bin_length 
norm_data = norm_data.astype(int) 
print(norm_data.max()) 
print(norm_data.min()) 
+0

pas fiable. J'ai utilisé numpy.clip à la fin. –

+0

écrêtage à la fois 0 et n_bins - 1 –