histograma array python numpy matplotlib scipy plot

array - histograma python



haciendo cuadro de caja en matplotlib con numpy y scipy en Python (2)

Tengo una matriz de 2 días que contiene pares de valores y me gustaría hacer una gráfica de caja de los valores y por diferentes contenedores de los valores de x. Es decir, si la matriz es:

my_array = array([[1, 40.5], [4.5, 60], ...]])

entonces me gustaría bin my_array [:, 0] y luego para cada uno de los bins, producir un diagrama de caja de los valores my_array [:,] correspondientes que caen en cada cuadro. Así que, al final, quiero que la trama contenga varias casillas, muchas diagramas de cajas.

Intenté lo siguiente:

min_x = min(my_array[:, 0]) max_x = max(my_array[:, 1]) num_bins = 3 bins = linspace(min_x, max_x, num_bins) elts_to_bins = digitize(my_array[:, 0], bins)

Sin embargo, esto me da valores en elts_to_bins que van del 1 al 3. Pensé que debería obtener índices basados ​​en 0 para los bins, y solo quería 3 bins. Supongo que esto se debe a alguna dificultad con la representación de los contenedores en linspace frente a digitalizar.

¿Cuál es la forma más fácil de lograr esto? Quiero num_bins-muchos bins igualmente espaciados, con el primer bin que contiene la mitad inferior de los datos y el bin superior que contiene la mitad superior ... es decir, quiero que cada punto de datos caiga en un bin, de modo que pueda hacer un cuadro de caja.

Gracias.


Obtendrá el tercer contenedor para el valor máximo en el conjunto (supongo que tiene un error tipográfico allí, y max_x debería ser "max (my_array [:, 0])" en lugar de "max (my_array [:, 1 ]) "). Puede evitar esto agregando 1 (o cualquier número positivo) al último contenedor.

Además, si lo entiendo correctamente, quiere bin una variable por otra, por lo que mi ejemplo a continuación muestra eso. Si está utilizando recarrays (que son mucho más lentos) también hay varias funciones en matplotlib.mlab (por ejemplo, mlab.rec_groupby, etc.) que hacen este tipo de cosas.

De todos modos, al final, es posible que tenga algo así (para bin x por los valores en y, suponiendo que xey son de la misma longitud)

def bin_by(x, y, nbins=30): """ Bin x by y. Returns the binned "x" values and the left edges of the bins """ bins = np.linspace(y.min(), y.max(), nbins+1) # To avoid extra bin for the max value bins[-1] += 1 indicies = np.digitize(y, bins) output = [] for i in xrange(1, len(bins)): output.append(x[indicies==i]) # Just return the left edges of the bins bins = bins[:-1] return output, bins

Como un ejemplo rápido:

In [3]: x = np.random.random((100, 2)) In [4]: binned_values, bins = bin_by(x[:,0], x[:,1], 2) In [5]: binned_values Out[5]: [array([ 0.59649575, 0.07082605, 0.7191498 , 0.4026375 , 0.06611863, 0.01473529, 0.45487203, 0.39942696, 0.02342408, 0.04669615, 0.58294003, 0.59510434, 0.76255006, 0.76685052, 0.26108928, 0.7640156 , 0.01771553, 0.38212975, 0.74417014, 0.38217517, 0.73909022, 0.21068663, 0.9103707 , 0.83556636, 0.34277006, 0.38007865, 0.18697416, 0.64370535, 0.68292336, 0.26142583, 0.50457354, 0.63071319, 0.87525221, 0.86509534, 0.96382375, 0.57556343, 0.55860405, 0.36392931, 0.93638048, 0.66889756, 0.46140831, 0.01675165, 0.15401495, 0.10813141, 0.03876953, 0.65967335, 0.86803192, 0.94835281, 0.44950182]), array([ 0.9249993 , 0.02682873, 0.89439141, 0.26415792, 0.42771144, 0.12292614, 0.44790357, 0.64692616, 0.14871052, 0.55611472, 0.72340179, 0.55335053, 0.07967047, 0.95725514, 0.49737279, 0.99213794, 0.7604765 , 0.56719713, 0.77828727, 0.77046566, 0.15060196, 0.39199123, 0.78904624, 0.59974575, 0.6965413 , 0.52664095, 0.28629324, 0.21838664, 0.47305751, 0.3544522 , 0.57704906, 0.1023201 , 0.76861237, 0.88862359, 0.29310836, 0.22079126, 0.84966201, 0.9376939 , 0.95449215, 0.10856864, 0.86655289, 0.57835533, 0.32831162, 0.1673871 , 0.55742108, 0.02436965, 0.45261232, 0.31552715, 0.56666458, 0.24757898, 0.8674747 ])]

¡Espero que esto ayude un poco!


Numpy tiene una función dedicada para crear histogramas de la manera que necesita:

histogram(a, bins=10, range=None, normed=False, weights=None, new=None)

que puedes usar como:

(hist_data, bin_edges) = histogram(my_array[:,0], weights=my_array[:,1])

El punto clave aquí es usar el argumento de weights : cada valor a[i] aportará weights[i] al histograma. Ejemplo:

a = [0, 1] weights = [10, 2]

describe 10 puntos en x = 0 y 2 puntos en x = 1.

Puede establecer el número de contenedores, o los límites del bins , con el argumento de bins (consulte la documentación oficial para obtener más información).

El histograma se puede trazar con algo como:

bar(bin_edges[:-1], hist_data)

Si solo necesita hacer un gráfico de histograma, la función hist () similar puede trazar directamente el histograma:

hist(my_array[:,0], weights=my_array[:,1])